clean up & save onboarding process as state
This commit is contained in:
@@ -1,6 +1,19 @@
|
||||
import { useEffect } from 'react';
|
||||
import { Outlet } from 'react-router-dom';
|
||||
|
||||
import { useOnboarding } from '@stores/onboarding';
|
||||
import { useStronghold } from '@stores/stronghold';
|
||||
|
||||
export function AuthCreateScreen() {
|
||||
const [step, tmpPrivkey] = useOnboarding((state) => [state.step, state.tempPrivkey]);
|
||||
const setPrivkey = useStronghold((state) => state.setPrivkey);
|
||||
|
||||
useEffect(() => {
|
||||
if (step) {
|
||||
setPrivkey(tmpPrivkey);
|
||||
}
|
||||
}, [tmpPrivkey]);
|
||||
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
<Outlet />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { BaseDirectory, writeTextFile } from '@tauri-apps/plugin-fs';
|
||||
import { generatePrivateKey, getPublicKey, nip19 } from 'nostr-tools';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { createAccount } from '@libs/storage';
|
||||
@@ -17,7 +17,9 @@ export function CreateStep1Screen() {
|
||||
const queryClient = useQueryClient();
|
||||
const navigate = useNavigate();
|
||||
const setPrivkey = useStronghold((state) => state.setPrivkey);
|
||||
const setTempPrivkey = useOnboarding((state) => state.setTempPrivkey);
|
||||
const setPubkey = useOnboarding((state) => state.setPubkey);
|
||||
const setStep = useOnboarding((state) => state.setStep);
|
||||
|
||||
const [privkeyInput, setPrivkeyInput] = useState('password');
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -61,8 +63,9 @@ export function CreateStep1Screen() {
|
||||
const submit = () => {
|
||||
setLoading(true);
|
||||
|
||||
setPubkey(pubkey);
|
||||
setPrivkey(privkey);
|
||||
setTempPrivkey(privkey); // only use if user close app and reopen it
|
||||
setPubkey(pubkey);
|
||||
|
||||
account.mutate({
|
||||
npub,
|
||||
@@ -75,6 +78,11 @@ export function CreateStep1Screen() {
|
||||
setTimeout(() => navigate('/auth/create/step-2', { replace: true }), 1200);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// save current step, if user close app and reopen it
|
||||
setStep('/auth/create/step-1');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="mx-auto w-full max-w-md">
|
||||
<div className="mb-8 text-center">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Resolver, useForm } from 'react-hook-form';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
@@ -30,13 +30,13 @@ const resolver: Resolver<FormValues> = async (values) => {
|
||||
|
||||
export function CreateStep2Screen() {
|
||||
const navigate = useNavigate();
|
||||
const setStep = useOnboarding((state) => state.setStep);
|
||||
const pubkey = useOnboarding((state) => state.pubkey);
|
||||
const privkey = useStronghold((state) => state.privkey);
|
||||
|
||||
const [passwordInput, setPasswordInput] = useState('password');
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const privkey = useStronghold((state) => state.privkey);
|
||||
const pubkey = useOnboarding((state) => state.pubkey);
|
||||
|
||||
const { save } = useSecureStorage();
|
||||
|
||||
// toggle private key
|
||||
@@ -72,6 +72,11 @@ export function CreateStep2Screen() {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// save current step, if user close app and reopen it
|
||||
setStep('/auth/create/step-2');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="mx-auto w-full max-w-md">
|
||||
<div className="mb-8 text-center">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
@@ -10,19 +10,20 @@ import { ArrowRightCircleIcon } from '@shared/icons/arrowRightCircle';
|
||||
import { Image } from '@shared/image';
|
||||
|
||||
import { DEFAULT_AVATAR } from '@stores/constants';
|
||||
import { useOnboarding } from '@stores/onboarding';
|
||||
|
||||
import { usePublish } from '@utils/hooks/usePublish';
|
||||
import { useNostr } from '@utils/hooks/useNostr';
|
||||
|
||||
export function CreateStep3Screen() {
|
||||
const { publish } = usePublish();
|
||||
|
||||
const navigate = useNavigate();
|
||||
const setStep = useOnboarding((state) => state.setStep);
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [picture, setPicture] = useState(DEFAULT_AVATAR);
|
||||
const [banner, setBanner] = useState('');
|
||||
|
||||
const { publish } = useNostr();
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
@@ -57,6 +58,11 @@ export function CreateStep3Screen() {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// save current step, if user close app and reopen it
|
||||
setStep('/auth/create/step-3');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="mx-auto w-full max-w-md">
|
||||
<div className="mb-8 text-center">
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
import { useEffect } from 'react';
|
||||
import { Outlet } from 'react-router-dom';
|
||||
|
||||
import { useOnboarding } from '@stores/onboarding';
|
||||
import { useStronghold } from '@stores/stronghold';
|
||||
|
||||
export function AuthImportScreen() {
|
||||
const [step, tmpPrivkey] = useOnboarding((state) => [state.step, state.tempPrivkey]);
|
||||
const setPrivkey = useStronghold((state) => state.setPrivkey);
|
||||
|
||||
useEffect(() => {
|
||||
if (step) {
|
||||
setPrivkey(tmpPrivkey);
|
||||
}
|
||||
}, [tmpPrivkey]);
|
||||
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
<Outlet />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { getPublicKey, nip19 } from 'nostr-tools';
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Resolver, useForm } from 'react-hook-form';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
@@ -34,7 +34,9 @@ export function ImportStep1Screen() {
|
||||
const queryClient = useQueryClient();
|
||||
const navigate = useNavigate();
|
||||
const setPrivkey = useStronghold((state) => state.setPrivkey);
|
||||
const setTempPubkey = useOnboarding((state) => state.setTempPrivkey);
|
||||
const setPubkey = useOnboarding((state) => state.setPubkey);
|
||||
const setStep = useOnboarding((state) => state.setStep);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
@@ -72,10 +74,9 @@ export function ImportStep1Screen() {
|
||||
const pubkey = getPublicKey(privkey);
|
||||
const npub = nip19.npubEncode(pubkey);
|
||||
|
||||
// use for onboarding process only
|
||||
setPubkey(pubkey);
|
||||
// add stronghold state
|
||||
setPrivkey(privkey);
|
||||
setTempPubkey(privkey); // only use if user close app and reopen it
|
||||
setPubkey(pubkey);
|
||||
|
||||
// add account to local database
|
||||
account.mutate({
|
||||
@@ -91,11 +92,16 @@ export function ImportStep1Screen() {
|
||||
} catch (error) {
|
||||
setError('privkey', {
|
||||
type: 'custom',
|
||||
message: 'Private Key is invalid, please check again',
|
||||
message: 'Private key is invalid, please check again',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// save current step, if user close app and reopen it
|
||||
setStep('/auth/import/step-1');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="mx-auto w-full max-w-md">
|
||||
<div className="mb-8 text-center">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Resolver, useForm } from 'react-hook-form';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
@@ -30,13 +30,13 @@ const resolver: Resolver<FormValues> = async (values) => {
|
||||
|
||||
export function ImportStep2Screen() {
|
||||
const navigate = useNavigate();
|
||||
const setStep = useOnboarding((state) => state.setStep);
|
||||
const pubkey = useOnboarding((state) => state.pubkey);
|
||||
const privkey = useStronghold((state) => state.privkey);
|
||||
|
||||
const [passwordInput, setPasswordInput] = useState('password');
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const privkey = useStronghold((state) => state.privkey);
|
||||
const pubkey = useOnboarding((state) => state.pubkey);
|
||||
|
||||
const { save } = useSecureStorage();
|
||||
|
||||
// toggle private key
|
||||
@@ -72,6 +72,11 @@ export function ImportStep2Screen() {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// save current step, if user close app and reopen it
|
||||
setStep('/auth/import/step-2');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="mx-auto w-full max-w-md">
|
||||
<div className="mb-8 text-center">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { User } from '@app/auth/components/user';
|
||||
@@ -8,12 +8,15 @@ import { updateLastLogin } from '@libs/storage';
|
||||
|
||||
import { ArrowRightCircleIcon, LoaderIcon } from '@shared/icons';
|
||||
|
||||
import { useOnboarding } from '@stores/onboarding';
|
||||
|
||||
import { useAccount } from '@utils/hooks/useAccount';
|
||||
import { useNostr } from '@utils/hooks/useNostr';
|
||||
|
||||
export function ImportStep3Screen() {
|
||||
const navigate = useNavigate();
|
||||
const queryClient = useQueryClient();
|
||||
const navigate = useNavigate();
|
||||
const setStep = useOnboarding((state) => state.setStep);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
@@ -39,6 +42,11 @@ export function ImportStep3Screen() {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// save current step, if user close app and reopen it
|
||||
setStep('/auth/import/step-3');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="mx-auto w-full max-w-md">
|
||||
<div className="mb-8 text-center">
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
import { useEffect } from 'react';
|
||||
import { Outlet } from 'react-router-dom';
|
||||
|
||||
import { useOnboarding } from '@stores/onboarding';
|
||||
import { useStronghold } from '@stores/stronghold';
|
||||
|
||||
export function OnboardingScreen() {
|
||||
const [step, tmpPrivkey] = useOnboarding((state) => [state.step, state.tempPrivkey]);
|
||||
const setPrivkey = useStronghold((state) => state.setPrivkey);
|
||||
|
||||
useEffect(() => {
|
||||
if (step) {
|
||||
setPrivkey(tmpPrivkey);
|
||||
}
|
||||
}, [tmpPrivkey]);
|
||||
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
<Outlet />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
|
||||
import { User } from '@app/auth/components/user';
|
||||
@@ -8,17 +8,18 @@ import { updateAccount } from '@libs/storage';
|
||||
|
||||
import { ArrowRightCircleIcon, CheckCircleIcon, LoaderIcon } from '@shared/icons';
|
||||
|
||||
import { useOnboarding } from '@stores/onboarding';
|
||||
|
||||
import { useAccount } from '@utils/hooks/useAccount';
|
||||
import { useNostr } from '@utils/hooks/useNostr';
|
||||
import { usePublish } from '@utils/hooks/usePublish';
|
||||
import { arrayToNIP02 } from '@utils/transform';
|
||||
|
||||
export function OnboardStep1Screen() {
|
||||
const queryClient = useQueryClient();
|
||||
const navigate = useNavigate();
|
||||
const setStep = useOnboarding((state) => state.setStep);
|
||||
|
||||
const { publish } = usePublish();
|
||||
const { fetchNotes } = useNostr();
|
||||
const { publish, fetchNotes } = useNostr();
|
||||
const { account } = useAccount();
|
||||
const { status, data } = useQuery(['trending-profiles'], async () => {
|
||||
const res = await fetch('https://api.nostr.band/v0/trending/profiles');
|
||||
@@ -62,6 +63,11 @@ export function OnboardStep1Screen() {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// save current step, if user close app and reopen it
|
||||
setStep('/auth/onboarding');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="mx-auto w-full max-w-md">
|
||||
<div className="mb-8 text-center">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
|
||||
import { createBlock } from '@libs/storage';
|
||||
@@ -6,6 +6,7 @@ import { createBlock } from '@libs/storage';
|
||||
import { ArrowRightCircleIcon, CheckCircleIcon, LoaderIcon } from '@shared/icons';
|
||||
|
||||
import { BLOCK_KINDS } from '@stores/constants';
|
||||
import { useOnboarding } from '@stores/onboarding';
|
||||
|
||||
const data = [
|
||||
{ hashtag: '#bitcoin' },
|
||||
@@ -27,6 +28,7 @@ const data = [
|
||||
|
||||
export function OnboardStep2Screen() {
|
||||
const navigate = useNavigate();
|
||||
const setStep = useOnboarding((state) => state.setStep);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [tags, setTags] = useState(new Set<string>());
|
||||
@@ -57,6 +59,11 @@ export function OnboardStep2Screen() {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// save current step, if user close app and reopen it
|
||||
setStep('/auth/onboarding/step-2');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="mx-auto w-full max-w-md">
|
||||
<div className="mb-8 text-center">
|
||||
|
||||
@@ -10,17 +10,19 @@ import { createRelay } from '@libs/storage';
|
||||
import { ArrowRightCircleIcon, CheckCircleIcon, LoaderIcon } from '@shared/icons';
|
||||
|
||||
import { FULL_RELAYS } from '@stores/constants';
|
||||
import { useOnboarding } from '@stores/onboarding';
|
||||
|
||||
import { useAccount } from '@utils/hooks/useAccount';
|
||||
import { usePublish } from '@utils/hooks/usePublish';
|
||||
import { useNostr } from '@utils/hooks/useNostr';
|
||||
|
||||
export function OnboardStep3Screen() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [setStep, clearStep] = useOnboarding((state) => [state.setStep, state.clearStep]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [relays, setRelays] = useState(new Set<string>());
|
||||
|
||||
const { publish } = usePublish();
|
||||
const { publish } = useNostr();
|
||||
const { account } = useAccount();
|
||||
const { fetcher, relayUrls } = useNDK();
|
||||
const { status, data } = useQuery(
|
||||
@@ -48,6 +50,9 @@ export function OnboardStep3Screen() {
|
||||
}
|
||||
);
|
||||
|
||||
// save current step, if user close app and reopen it
|
||||
setStep('/auth/onboarding/step-3');
|
||||
|
||||
const toggleRelay = (relay: string) => {
|
||||
if (relays.has(relay)) {
|
||||
setRelays((prev) => {
|
||||
@@ -76,6 +81,7 @@ export function OnboardStep3Screen() {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
clearStep();
|
||||
navigate('/', { replace: true });
|
||||
}, 1000);
|
||||
} catch (e) {
|
||||
|
||||
@@ -9,7 +9,9 @@ export function WelcomeScreen() {
|
||||
async function setWindow() {
|
||||
await appWindow.setSize(new LogicalSize(400, 500));
|
||||
await appWindow.setResizable(false);
|
||||
await appWindow.center();
|
||||
}
|
||||
|
||||
setWindow();
|
||||
|
||||
return () => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useCallback, useState } from 'react';
|
||||
import { EnterIcon } from '@shared/icons';
|
||||
import { MediaUploader } from '@shared/mediaUploader';
|
||||
|
||||
import { usePublish } from '@utils/hooks/usePublish';
|
||||
import { useNostr } from '@utils/hooks/useNostr';
|
||||
|
||||
export function ChatMessageForm({
|
||||
receiverPubkey,
|
||||
@@ -14,7 +14,7 @@ export function ChatMessageForm({
|
||||
userPubkey: string;
|
||||
userPrivkey: string;
|
||||
}) {
|
||||
const { publish } = usePublish();
|
||||
const { publish } = useNostr();
|
||||
const [value, setValue] = useState('');
|
||||
|
||||
const encryptMessage = useCallback(async () => {
|
||||
|
||||
@@ -12,14 +12,14 @@ import { Image } from '@shared/image';
|
||||
import { BLOCK_KINDS, DEFAULT_AVATAR } from '@stores/constants';
|
||||
import { ADD_IMAGEBLOCK_SHORTCUT } from '@stores/shortcuts';
|
||||
|
||||
import { usePublish } from '@utils/hooks/usePublish';
|
||||
import { useNostr } from '@utils/hooks/useNostr';
|
||||
import { useImageUploader } from '@utils/hooks/useUploader';
|
||||
|
||||
export function ImageModal() {
|
||||
const queryClient = useQueryClient();
|
||||
const upload = useImageUploader();
|
||||
|
||||
const { publish } = usePublish();
|
||||
const { publish } = useNostr();
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
@@ -4,8 +4,6 @@ import { useEffect, useRef } from 'react';
|
||||
import { useNDK } from '@libs/ndk/provider';
|
||||
import { createNote } from '@libs/storage';
|
||||
|
||||
import { useNote } from '@stores/note';
|
||||
|
||||
import { useAccount } from '@utils/hooks/useAccount';
|
||||
|
||||
export function useNewsfeed() {
|
||||
@@ -15,8 +13,6 @@ export function useNewsfeed() {
|
||||
const { ndk } = useNDK();
|
||||
const { status, account } = useAccount();
|
||||
|
||||
const toggleHasNewNote = useNote((state) => state.toggleHasNewNote);
|
||||
|
||||
useEffect(() => {
|
||||
if (status === 'success' && account) {
|
||||
const filter: NDKFilter = {
|
||||
@@ -37,8 +33,6 @@ export function useNewsfeed() {
|
||||
event.content,
|
||||
event.created_at
|
||||
);
|
||||
// notify user about created note
|
||||
toggleHasNewNote(true);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { invoke } from '@tauri-apps/api/tauri';
|
||||
import { platform } from '@tauri-apps/plugin-os';
|
||||
import { appWindow } from '@tauri-apps/plugin-window';
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { getActiveAccount, updateLastLogin } from '@libs/storage';
|
||||
|
||||
@@ -10,47 +8,76 @@ import { LoaderIcon } from '@shared/icons';
|
||||
import { useNostr } from '@utils/hooks/useNostr';
|
||||
|
||||
const account = await getActiveAccount();
|
||||
const osPlatform = await platform();
|
||||
|
||||
if (osPlatform !== 'macos') {
|
||||
appWindow.setDecorations(false);
|
||||
}
|
||||
|
||||
export function SplashScreen() {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const { fetchChats, fetchNotes } = useNostr();
|
||||
|
||||
if (!account) {
|
||||
setTimeout(async () => await invoke('close_splashscreen'), 500);
|
||||
}
|
||||
|
||||
const skip = async () => {
|
||||
await invoke('close_splashscreen');
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
async function prefetch() {
|
||||
const onboarding = localStorage.getItem('onboarding');
|
||||
const step = JSON.parse(onboarding).state.step || null;
|
||||
if (step) await invoke('close_splashscreen');
|
||||
|
||||
const notes = await fetchNotes();
|
||||
const chats = await fetchChats();
|
||||
if (notes && chats) {
|
||||
|
||||
if (notes.status === 'ok' && chats.status === 'ok') {
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
await updateLastLogin(now);
|
||||
invoke('close_splashscreen');
|
||||
} else {
|
||||
setLoading(false);
|
||||
console.log('fetch notes failed, error: ', notes.message);
|
||||
console.log('fetch chats failed, error: ', chats.message);
|
||||
}
|
||||
}
|
||||
|
||||
if (account) {
|
||||
if (account && loading) {
|
||||
prefetch();
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (!account) {
|
||||
setTimeout(() => invoke('close_splashscreen'), 1000);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative flex h-screen w-screen items-center justify-center bg-black">
|
||||
<div data-tauri-drag-region className="absolute left-0 top-0 z-10 h-11 w-full" />
|
||||
<div className="flex min-h-0 w-full flex-1 items-center justify-center">
|
||||
<div className="flex flex-col items-center justify-center gap-4">
|
||||
<LoaderIcon className="h-6 w-6 animate-spin text-white" />
|
||||
<div className="flex flex-col gap-1 text-center">
|
||||
<h3 className="font-semibold leading-none text-white">Prefetching data</h3>
|
||||
<p className="text-sm leading-none text-white/50">
|
||||
This may take a few seconds, please don't close app.
|
||||
</p>
|
||||
</div>
|
||||
{loading ? (
|
||||
<div className="mt-2 flex flex-col gap-1 text-center">
|
||||
<h3 className="text-lg font-semibold leading-none text-white">
|
||||
Prefetching data
|
||||
</h3>
|
||||
<p className="text-white/50">
|
||||
This may take a few seconds, please don't close app.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="mt-2 flex flex-col gap-1 text-center">
|
||||
<h3 className="text-lg font-semibold leading-none text-white">
|
||||
Something wrong!
|
||||
</h3>
|
||||
<p className="text-white/50">
|
||||
Prefetching process failed, click skip to continue.
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
onClick={skip}
|
||||
className="mx-auto mt-4 inline-flex h-10 w-max items-center justify-center rounded-md bg-white/10 px-8 text-sm font-medium leading-none text-white backdrop-blur-xl hover:bg-white/20"
|
||||
>
|
||||
Skip
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user