mirror of
https://github.com/Radiquum/AniX.git
synced 2025-04-06 00:04:39 +00:00
feat: add disclaimer on first launch
fix: check store hydration before loading pages fix: check user store before loading pages
This commit is contained in:
parent
a64e4f2036
commit
2c8460c6b0
4 changed files with 92 additions and 14 deletions
1
TODO.md
1
TODO.md
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
## Важное
|
## Важное
|
||||||
|
|
||||||
- [ ] Уведомление о том что мы не связаны с аниксарт при первом открытии
|
|
||||||
- [ ] Кнопка сброса всех настроек
|
- [ ] Кнопка сброса всех настроек
|
||||||
- [ ] Список изменений при входе
|
- [ ] Список изменений при входе
|
||||||
|
|
||||||
|
|
58
app/App.tsx
58
app/App.tsx
|
@ -1,20 +1,74 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { useUserStore } from "./store/auth";
|
import { useUserStore } from "./store/auth";
|
||||||
|
import { usePreferencesStore } from "./store/preferences";
|
||||||
import { Navbar } from "./components/Navbar/Navbar";
|
import { Navbar } from "./components/Navbar/Navbar";
|
||||||
import { Inter } from "next/font/google";
|
import { Inter } from "next/font/google";
|
||||||
import { useEffect } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
import { Button, Modal } from "flowbite-react";
|
||||||
|
import { Spinner } from "./components/Spinner/Spinner";
|
||||||
const inter = Inter({ subsets: ["latin"] });
|
const inter = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
export const App = (props) => {
|
export const App = (props) => {
|
||||||
|
const preferencesStore = usePreferencesStore();
|
||||||
const userStore = useUserStore((state) => state);
|
const userStore = useUserStore((state) => state);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
userStore.checkAuth();
|
userStore.checkAuth();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
if (!preferencesStore._hasHydrated && !userStore._hasHydrated) {
|
||||||
|
return (
|
||||||
|
<body
|
||||||
|
className={`${inter.className} overflow-x-hidden dark:bg-[#0d1117] dark:text-white h-screen flex justify-center items-center`}
|
||||||
|
>
|
||||||
|
<Spinner />
|
||||||
|
</body>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userStore.state === "loading") {
|
||||||
|
return (
|
||||||
|
<body
|
||||||
|
className={`${inter.className} overflow-x-hidden dark:bg-[#0d1117] dark:text-white h-screen flex justify-center items-center`}
|
||||||
|
>
|
||||||
|
<Spinner />
|
||||||
|
</body>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<body className={`${inter.className} overflow-x-hidden dark:bg-[#0d1117] dark:text-white`}>
|
<body
|
||||||
|
className={`${inter.className} overflow-x-hidden dark:bg-[#0d1117] dark:text-white`}
|
||||||
|
>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
{props.children}
|
{props.children}
|
||||||
|
<Modal show={preferencesStore.params.isFirstLaunch}>
|
||||||
|
<Modal.Header>Внимание</Modal.Header>
|
||||||
|
<Modal.Body>
|
||||||
|
<p>
|
||||||
|
Данный сайт не связан с разработчиками приложения Anixart, это
|
||||||
|
неофициальная имплементация веб клиента для этого приложения.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Используя данный веб-сайт вы принимаете что мы не несём
|
||||||
|
ответственности за ваш аккаунт.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
На сайте могут присутствовать ошибки и не доработки, а так-же
|
||||||
|
отсутствующий функционал.
|
||||||
|
</p>
|
||||||
|
</Modal.Body>
|
||||||
|
<Modal.Footer>
|
||||||
|
<Button
|
||||||
|
color={"blue"}
|
||||||
|
onClick={() => {
|
||||||
|
preferencesStore.setParams({ isFirstLaunch: false });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Принимаю
|
||||||
|
</Button>
|
||||||
|
</Modal.Footer>
|
||||||
|
</Modal>
|
||||||
</body>
|
</body>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,26 +3,40 @@ import { create } from "zustand";
|
||||||
import { getJWT, removeJWT, fetchDataViaGet } from "#/api/utils";
|
import { getJWT, removeJWT, fetchDataViaGet } from "#/api/utils";
|
||||||
|
|
||||||
interface userState {
|
interface userState {
|
||||||
isAuth: boolean
|
_hasHydrated: boolean;
|
||||||
user: Object | null
|
isAuth: boolean;
|
||||||
token: string | null
|
user: Object | null;
|
||||||
state: string,
|
token: string | null;
|
||||||
login: (user: Object, token: string) => void
|
state: string;
|
||||||
logout: () => void
|
login: (user: Object, token: string) => void;
|
||||||
checkAuth: () => void
|
logout: () => void;
|
||||||
|
checkAuth: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useUserStore = create<userState>((set, get) => ({
|
export const useUserStore = create<userState>((set, get) => ({
|
||||||
|
_hasHydrated: false,
|
||||||
isAuth: false,
|
isAuth: false,
|
||||||
user: null,
|
user: null,
|
||||||
token: null,
|
token: null,
|
||||||
state: "loading",
|
state: "loading",
|
||||||
|
|
||||||
login: (user: Object, token: string) => {
|
login: (user: Object, token: string) => {
|
||||||
set({ isAuth: true, user: user, token: token, state: "finished" });
|
set({
|
||||||
|
isAuth: true,
|
||||||
|
user: user,
|
||||||
|
token: token,
|
||||||
|
state: "finished",
|
||||||
|
_hasHydrated: true,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
logout: () => {
|
logout: () => {
|
||||||
set({ isAuth: false, user: null, token: null, state: "finished" });
|
set({
|
||||||
|
isAuth: false,
|
||||||
|
user: null,
|
||||||
|
token: null,
|
||||||
|
state: "finished",
|
||||||
|
_hasHydrated: true,
|
||||||
|
});
|
||||||
removeJWT();
|
removeJWT();
|
||||||
},
|
},
|
||||||
checkAuth: () => {
|
checkAuth: () => {
|
||||||
|
@ -37,8 +51,8 @@ export const useUserStore = create<userState>((set, get) => ({
|
||||||
} else {
|
} else {
|
||||||
get().logout();
|
get().logout();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
_checkAuth()
|
_checkAuth();
|
||||||
} else {
|
} else {
|
||||||
get().logout();
|
get().logout();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { create } from "zustand";
|
||||||
import { persist } from "zustand/middleware";
|
import { persist } from "zustand/middleware";
|
||||||
|
|
||||||
interface preferencesState {
|
interface preferencesState {
|
||||||
|
_hasHydrated: boolean;
|
||||||
flags: {
|
flags: {
|
||||||
// saveSearchHistory: boolean;
|
// saveSearchHistory: boolean;
|
||||||
saveWatchHistory: boolean;
|
saveWatchHistory: boolean;
|
||||||
|
@ -16,6 +17,7 @@ interface preferencesState {
|
||||||
// accent: string;
|
// accent: string;
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
setHasHydrated: (state: boolean) => void;
|
||||||
setFlags: (flags: preferencesState["flags"]) => void;
|
setFlags: (flags: preferencesState["flags"]) => void;
|
||||||
setParams: (params: preferencesState["params"]) => void;
|
setParams: (params: preferencesState["params"]) => void;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +25,7 @@ interface preferencesState {
|
||||||
export const usePreferencesStore = create<preferencesState>()(
|
export const usePreferencesStore = create<preferencesState>()(
|
||||||
persist(
|
persist(
|
||||||
(set, get) => ({
|
(set, get) => ({
|
||||||
|
_hasHydrated: false,
|
||||||
flags: {
|
flags: {
|
||||||
// saveSearchHistory: true,
|
// saveSearchHistory: true,
|
||||||
saveWatchHistory: true,
|
saveWatchHistory: true,
|
||||||
|
@ -31,6 +34,11 @@ export const usePreferencesStore = create<preferencesState>()(
|
||||||
params: {
|
params: {
|
||||||
isFirstLaunch: true,
|
isFirstLaunch: true,
|
||||||
},
|
},
|
||||||
|
setHasHydrated: (state) => {
|
||||||
|
set({
|
||||||
|
_hasHydrated: state,
|
||||||
|
});
|
||||||
|
},
|
||||||
setFlags(flags) {
|
setFlags(flags) {
|
||||||
set({ flags });
|
set({ flags });
|
||||||
},
|
},
|
||||||
|
@ -40,6 +48,9 @@ export const usePreferencesStore = create<preferencesState>()(
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
name: "preferences",
|
name: "preferences",
|
||||||
|
onRehydrateStorage: (state) => {
|
||||||
|
return () => state.setHasHydrated(true);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Reference in a new issue