mirror of
https://github.com/Qortal/qapp-core.git
synced 2025-07-13 20:51:21 +00:00
added useAuth as export
This commit is contained in:
parent
8da43d1fa8
commit
78af0d1750
@ -5,7 +5,7 @@ import React, {
|
||||
useEffect,
|
||||
useMemo,
|
||||
} from "react";
|
||||
import { useAuth, UseAuthProps } from "../hooks/useAuth";
|
||||
import { useAuth, UseAuthProps } from "../hooks/useInitializeAuth";
|
||||
import { useResources } from "../hooks/useResources";
|
||||
import { useAppInfo } from "../hooks/useAppInfo";
|
||||
import { useIdentifiers } from "../hooks/useIdentifiers";
|
||||
@ -15,10 +15,8 @@ import { IndexManager } from "../components/IndexManager/IndexManager";
|
||||
import { useIndexes } from "../hooks/useIndexes";
|
||||
import { useProgressStore } from "../state/video";
|
||||
import { GlobalPipPlayer } from "../hooks/useGlobalPipPlayer";
|
||||
import { Location, NavigateFunction } from "react-router-dom";
|
||||
import { MultiPublishDialog } from "../components/MultiPublish/MultiPublishDialog";
|
||||
import { useMultiplePublishStore } from "../state/multiplePublish";
|
||||
import { useGlobalPlayerStore } from "../state/pip";
|
||||
|
||||
// ✅ Define Global Context Type
|
||||
interface GlobalContextType {
|
||||
@ -28,7 +26,7 @@ interface GlobalContextType {
|
||||
identifierOperations: ReturnType<typeof useIdentifiers>;
|
||||
persistentOperations: ReturnType<typeof usePersistentStore>;
|
||||
indexOperations: ReturnType<typeof useIndexes>;
|
||||
enableGlobalVideoFeature: boolean
|
||||
enableGlobalVideoFeature: boolean;
|
||||
}
|
||||
|
||||
// ✅ Define Config Type for Hook Options
|
||||
@ -39,7 +37,7 @@ interface GlobalProviderProps {
|
||||
auth?: UseAuthProps;
|
||||
appName: string;
|
||||
publicSalt: string;
|
||||
enableGlobalVideoFeature?: boolean
|
||||
enableGlobalVideoFeature?: boolean;
|
||||
};
|
||||
|
||||
toastStyle?: CSSProperties;
|
||||
@ -48,9 +46,6 @@ interface GlobalProviderProps {
|
||||
// ✅ Create Context with Proper Type
|
||||
export const GlobalContext = createContext<GlobalContextType | null>(null);
|
||||
|
||||
|
||||
|
||||
|
||||
// 🔹 Global Provider (Handles Multiple Hooks)
|
||||
export const GlobalProvider = ({
|
||||
children,
|
||||
@ -59,7 +54,7 @@ export const GlobalProvider = ({
|
||||
}: GlobalProviderProps) => {
|
||||
// ✅ Call hooks and pass in options dynamically
|
||||
const auth = useAuth(config?.auth || {});
|
||||
const isPublishing = useMultiplePublishStore((s)=> s.isPublishing);
|
||||
const isPublishing = useMultiplePublishStore((s) => s.isPublishing);
|
||||
const appInfo = useAppInfo(config.appName, config?.publicSalt);
|
||||
const lists = useResources();
|
||||
const identifierOperations = useIdentifiers(
|
||||
@ -80,9 +75,16 @@ export const GlobalProvider = ({
|
||||
identifierOperations,
|
||||
persistentOperations,
|
||||
indexOperations,
|
||||
enableGlobalVideoFeature: config?.enableGlobalVideoFeature || false
|
||||
enableGlobalVideoFeature: config?.enableGlobalVideoFeature || false,
|
||||
}),
|
||||
[auth, lists, appInfo, identifierOperations, persistentOperations, config?.enableGlobalVideoFeature]
|
||||
[
|
||||
auth,
|
||||
lists,
|
||||
appInfo,
|
||||
identifierOperations,
|
||||
persistentOperations,
|
||||
config?.enableGlobalVideoFeature,
|
||||
]
|
||||
);
|
||||
const { clearOldProgress } = useProgressStore();
|
||||
|
||||
@ -91,18 +93,10 @@ export const GlobalProvider = ({
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
||||
<GlobalContext.Provider value={contextValue}>
|
||||
{config?.enableGlobalVideoFeature && (
|
||||
<GlobalPipPlayer />
|
||||
)}
|
||||
|
||||
|
||||
|
||||
|
||||
{isPublishing && (
|
||||
<MultiPublishDialog />
|
||||
)}
|
||||
{config?.enableGlobalVideoFeature && <GlobalPipPlayer />}
|
||||
|
||||
{isPublishing && <MultiPublishDialog />}
|
||||
<Toaster
|
||||
position="top-center"
|
||||
toastOptions={{
|
||||
@ -115,7 +109,6 @@ export const GlobalProvider = ({
|
||||
|
||||
{children}
|
||||
</GlobalContext.Provider>
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,157 +1,83 @@
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useAuthStore } from "../state/auth";
|
||||
import { userAccountInfo } from "./useInitializeAuth";
|
||||
|
||||
// ✅ Define Types
|
||||
/**
|
||||
* Configuration for balance retrieval behavior.
|
||||
*/
|
||||
export type BalanceSetting =
|
||||
| {
|
||||
/** If `true`, the balance will be fetched only once when the app loads. */
|
||||
onlyOnMount: true;
|
||||
/** `interval` cannot be set when `onlyOnMount` is `true`. */
|
||||
interval?: never;
|
||||
}
|
||||
| {
|
||||
/** If `false` or omitted, balance will be updated periodically. */
|
||||
onlyOnMount?: false;
|
||||
/** The time interval (in milliseconds) for balance updates. */
|
||||
interval?: number;
|
||||
};
|
||||
|
||||
interface userAccountInfo {
|
||||
address: string;
|
||||
publicKey: string
|
||||
}
|
||||
export interface UseAuthProps {
|
||||
balanceSetting?: BalanceSetting;
|
||||
/** User will be prompted for authentication on start-up */
|
||||
authenticateOnMount?: boolean;
|
||||
userAccountInfo?: userAccountInfo | null
|
||||
}
|
||||
|
||||
export const useAuth = ({ balanceSetting, authenticateOnMount = true, userAccountInfo = null }: UseAuthProps) => {
|
||||
export const useAuth = () => {
|
||||
const address = useAuthStore((s) => s.address);
|
||||
const publicKey = useAuthStore((s) => s.publicKey);
|
||||
const name = useAuthStore((s) => s.name);
|
||||
const avatarUrl = useAuthStore((s) => s.avatarUrl);
|
||||
const balance = useAuthStore((s) => s.balance);
|
||||
const publicKey = useAuthStore((s) => s.publicKey);
|
||||
const name = useAuthStore((s) => s.name);
|
||||
const avatarUrl = useAuthStore((s) => s.avatarUrl);
|
||||
|
||||
const isLoadingUser = useAuthStore((s) => s.isLoadingUser);
|
||||
const isLoadingInitialBalance = useAuthStore((s) => s.isLoadingInitialBalance);
|
||||
const errorLoadingUser = useAuthStore((s) => s.errorLoadingUser);
|
||||
const isLoadingUser = useAuthStore((s) => s.isLoadingUser);
|
||||
const errorLoadingUser = useAuthStore((s) => s.errorLoadingUser);
|
||||
const setErrorLoadingUser = useAuthStore((s) => s.setErrorLoadingUser);
|
||||
const setIsLoadingUser = useAuthStore((s) => s.setIsLoadingUser);
|
||||
const setUser = useAuthStore((s) => s.setUser);
|
||||
const setName = useAuthStore((s) => s.setName);
|
||||
const authenticateUser = useCallback(
|
||||
async (userAccountInfo?: userAccountInfo) => {
|
||||
try {
|
||||
setErrorLoadingUser(null);
|
||||
setIsLoadingUser(true);
|
||||
|
||||
const setErrorLoadingUser = useAuthStore((s) => s.setErrorLoadingUser);
|
||||
const setIsLoadingUser = useAuthStore((s) => s.setIsLoadingUser);
|
||||
const setUser = useAuthStore((s) => s.setUser);
|
||||
const setBalance = useAuthStore((s) => s.setBalance);
|
||||
const account =
|
||||
userAccountInfo ||
|
||||
(await qortalRequest({
|
||||
action: "GET_USER_ACCOUNT",
|
||||
}));
|
||||
|
||||
|
||||
const balanceSetIntervalRef = useRef<null | ReturnType<typeof setInterval>>(null);
|
||||
|
||||
const authenticateUser = useCallback(async (userAccountInfo?: userAccountInfo) => {
|
||||
try {
|
||||
setErrorLoadingUser(null);
|
||||
setIsLoadingUser(true);
|
||||
|
||||
const account = userAccountInfo || await qortalRequest({
|
||||
action: "GET_USER_ACCOUNT",
|
||||
});
|
||||
|
||||
if (account?.address) {
|
||||
const nameData = await qortalRequest({
|
||||
action: "GET_PRIMARY_NAME",
|
||||
address: account.address,
|
||||
});
|
||||
setUser({ ...account, name: nameData || "" });
|
||||
if (account?.address) {
|
||||
const nameData = await qortalRequest({
|
||||
action: "GET_PRIMARY_NAME",
|
||||
address: account.address,
|
||||
});
|
||||
setUser({ ...account, name: nameData || "" });
|
||||
}
|
||||
} catch (error) {
|
||||
setErrorLoadingUser(
|
||||
error instanceof Error ? error.message : "Unable to authenticate"
|
||||
);
|
||||
} finally {
|
||||
setIsLoadingUser(false);
|
||||
}
|
||||
} catch (error) {
|
||||
setErrorLoadingUser(
|
||||
error instanceof Error ? error.message : "Unable to authenticate"
|
||||
);
|
||||
} finally {
|
||||
setIsLoadingUser(false);
|
||||
}
|
||||
}, [setErrorLoadingUser, setIsLoadingUser, setUser]);
|
||||
},
|
||||
[setErrorLoadingUser, setIsLoadingUser, setUser]
|
||||
);
|
||||
|
||||
const getBalance = useCallback(async (address: string): Promise<number> => {
|
||||
try {
|
||||
const response = await qortalRequest({
|
||||
action: "GET_BALANCE",
|
||||
address,
|
||||
});
|
||||
const userBalance = Number(response) || 0
|
||||
setBalance(userBalance);
|
||||
return userBalance
|
||||
} catch (error) {
|
||||
setBalance(0);
|
||||
return 0
|
||||
}
|
||||
}, [setBalance]);
|
||||
const switchName = useCallback(
|
||||
async (name: string) => {
|
||||
if (!name) throw new Error("No name provided");
|
||||
const response = await fetch(`/names/${name}`);
|
||||
if (!response?.ok) throw new Error("Error fetching name details");
|
||||
const nameInfo = await response.json();
|
||||
const currentAddress = useAuthStore.getState().address;
|
||||
|
||||
const balanceSetInterval = useCallback((address: string, interval: number) => {
|
||||
try {
|
||||
if (balanceSetIntervalRef.current) {
|
||||
clearInterval(balanceSetIntervalRef.current);
|
||||
}
|
||||
|
||||
let isCalling = false;
|
||||
balanceSetIntervalRef.current = setInterval(async () => {
|
||||
if (isCalling) return;
|
||||
isCalling = true;
|
||||
await getBalance(address);
|
||||
isCalling = false;
|
||||
}, interval);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}, [getBalance]);
|
||||
|
||||
useEffect(() => {
|
||||
if (authenticateOnMount) {
|
||||
authenticateUser();
|
||||
}
|
||||
if(userAccountInfo?.address && userAccountInfo?.publicKey){
|
||||
authenticateUser(userAccountInfo);
|
||||
}
|
||||
}, [authenticateOnMount, authenticateUser, userAccountInfo?.address, userAccountInfo?.publicKey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (address && (balanceSetting?.onlyOnMount || (balanceSetting?.interval && !isNaN(balanceSetting?.interval)))) {
|
||||
getBalance(address);
|
||||
}
|
||||
if (address && balanceSetting?.interval !== undefined && !isNaN(balanceSetting.interval)) {
|
||||
balanceSetInterval(address, balanceSetting.interval);
|
||||
}
|
||||
}, [balanceSetting?.onlyOnMount, balanceSetting?.interval, address, getBalance, balanceSetInterval]);
|
||||
|
||||
const manualGetBalance = useCallback(async () : Promise<number | Error> => {
|
||||
if(!address) throw new Error('Not authenticated')
|
||||
const res = await getBalance(address)
|
||||
return res
|
||||
}, [address])
|
||||
|
||||
return useMemo(() => ({
|
||||
address,
|
||||
publicKey,
|
||||
name,
|
||||
avatarUrl,
|
||||
balance,
|
||||
isLoadingUser,
|
||||
isLoadingInitialBalance,
|
||||
errorMessageLoadingUser: errorLoadingUser,
|
||||
authenticateUser,
|
||||
getBalance: manualGetBalance,
|
||||
}), [
|
||||
address,
|
||||
publicKey,
|
||||
name,
|
||||
avatarUrl,
|
||||
balance,
|
||||
isLoadingUser,
|
||||
isLoadingInitialBalance,
|
||||
errorLoadingUser,
|
||||
authenticateUser,
|
||||
manualGetBalance,
|
||||
]);
|
||||
if (nameInfo?.owner !== currentAddress)
|
||||
throw new Error(`This account does not own the name ${name}`);
|
||||
setName(name);
|
||||
},
|
||||
[setName]
|
||||
);
|
||||
return useMemo(
|
||||
() => ({
|
||||
address,
|
||||
publicKey,
|
||||
name,
|
||||
avatarUrl,
|
||||
isLoadingUser,
|
||||
errorMessageLoadingUser: errorLoadingUser,
|
||||
authenticateUser,
|
||||
switchName,
|
||||
}),
|
||||
[
|
||||
address,
|
||||
publicKey,
|
||||
name,
|
||||
avatarUrl,
|
||||
isLoadingUser,
|
||||
errorLoadingUser,
|
||||
authenticateUser,
|
||||
switchName,
|
||||
]
|
||||
);
|
||||
};
|
||||
|
48
src/hooks/useBalance.tsx
Normal file
48
src/hooks/useBalance.tsx
Normal file
@ -0,0 +1,48 @@
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useAuthStore } from "../state/auth";
|
||||
|
||||
export const useQortBalance = () => {
|
||||
const address = useAuthStore((s) => s.address);
|
||||
const setBalance = useAuthStore((s) => s.setBalance);
|
||||
const isLoadingInitialBalance = useAuthStore(
|
||||
(s) => s.isLoadingInitialBalance
|
||||
);
|
||||
const setIsLoadingBalance = useAuthStore((s) => s.setIsLoadingBalance);
|
||||
|
||||
const qortBalance = useAuthStore((s) => s.balance);
|
||||
|
||||
const getBalance = useCallback(
|
||||
async (address: string): Promise<number> => {
|
||||
try {
|
||||
setIsLoadingBalance(true);
|
||||
const response = await qortalRequest({
|
||||
action: "GET_BALANCE",
|
||||
address,
|
||||
});
|
||||
const userBalance = Number(response) || 0;
|
||||
setBalance(userBalance);
|
||||
return userBalance;
|
||||
} catch (error) {
|
||||
setBalance(0);
|
||||
return 0;
|
||||
} finally {
|
||||
setIsLoadingBalance(false);
|
||||
}
|
||||
},
|
||||
[setBalance]
|
||||
);
|
||||
|
||||
const manualGetBalance = useCallback(async (): Promise<number | Error> => {
|
||||
if (!address) throw new Error("Not authenticated");
|
||||
const res = await getBalance(address);
|
||||
return res;
|
||||
}, [address]);
|
||||
return useMemo(
|
||||
() => ({
|
||||
value: qortBalance,
|
||||
getBalance: manualGetBalance,
|
||||
isLoading: isLoadingInitialBalance,
|
||||
}),
|
||||
[qortBalance, manualGetBalance, isLoadingInitialBalance]
|
||||
);
|
||||
};
|
185
src/hooks/useInitializeAuth.tsx
Normal file
185
src/hooks/useInitializeAuth.tsx
Normal file
@ -0,0 +1,185 @@
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { useAuthStore } from "../state/auth";
|
||||
|
||||
// ✅ Define Types
|
||||
/**
|
||||
* Configuration for balance retrieval behavior.
|
||||
*/
|
||||
export type BalanceSetting =
|
||||
| {
|
||||
/** If `true`, the balance will be fetched only once when the app loads. */
|
||||
onlyOnMount: true;
|
||||
/** `interval` cannot be set when `onlyOnMount` is `true`. */
|
||||
interval?: never;
|
||||
}
|
||||
| {
|
||||
/** If `false` or omitted, balance will be updated periodically. */
|
||||
onlyOnMount?: false;
|
||||
/** The time interval (in milliseconds) for balance updates. */
|
||||
interval?: number;
|
||||
};
|
||||
|
||||
export interface userAccountInfo {
|
||||
address: string;
|
||||
publicKey: string;
|
||||
}
|
||||
export interface UseAuthProps {
|
||||
balanceSetting?: BalanceSetting;
|
||||
/** User will be prompted for authentication on start-up */
|
||||
authenticateOnMount?: boolean;
|
||||
userAccountInfo?: userAccountInfo | null;
|
||||
}
|
||||
|
||||
export const useAuth = ({
|
||||
balanceSetting,
|
||||
authenticateOnMount = true,
|
||||
userAccountInfo = null,
|
||||
}: UseAuthProps) => {
|
||||
const address = useAuthStore((s) => s.address);
|
||||
const publicKey = useAuthStore((s) => s.publicKey);
|
||||
const name = useAuthStore((s) => s.name);
|
||||
const avatarUrl = useAuthStore((s) => s.avatarUrl);
|
||||
|
||||
const isLoadingUser = useAuthStore((s) => s.isLoadingUser);
|
||||
const errorLoadingUser = useAuthStore((s) => s.errorLoadingUser);
|
||||
const setIsLoadingBalance = useAuthStore((s) => s.setIsLoadingBalance);
|
||||
|
||||
const setErrorLoadingUser = useAuthStore((s) => s.setErrorLoadingUser);
|
||||
const setIsLoadingUser = useAuthStore((s) => s.setIsLoadingUser);
|
||||
const setUser = useAuthStore((s) => s.setUser);
|
||||
const setBalance = useAuthStore((s) => s.setBalance);
|
||||
|
||||
const balanceSetIntervalRef = useRef<null | ReturnType<typeof setInterval>>(
|
||||
null
|
||||
);
|
||||
|
||||
const authenticateUser = useCallback(
|
||||
async (userAccountInfo?: userAccountInfo) => {
|
||||
try {
|
||||
setErrorLoadingUser(null);
|
||||
setIsLoadingUser(true);
|
||||
|
||||
const account =
|
||||
userAccountInfo ||
|
||||
(await qortalRequest({
|
||||
action: "GET_USER_ACCOUNT",
|
||||
}));
|
||||
|
||||
if (account?.address) {
|
||||
const nameData = await qortalRequest({
|
||||
action: "GET_PRIMARY_NAME",
|
||||
address: account.address,
|
||||
});
|
||||
setUser({ ...account, name: nameData || "" });
|
||||
}
|
||||
} catch (error) {
|
||||
setErrorLoadingUser(
|
||||
error instanceof Error ? error.message : "Unable to authenticate"
|
||||
);
|
||||
} finally {
|
||||
setIsLoadingUser(false);
|
||||
}
|
||||
},
|
||||
[setErrorLoadingUser, setIsLoadingUser, setUser]
|
||||
);
|
||||
|
||||
const getBalance = useCallback(
|
||||
async (address: string): Promise<number> => {
|
||||
try {
|
||||
setIsLoadingBalance(true);
|
||||
const response = await qortalRequest({
|
||||
action: "GET_BALANCE",
|
||||
address,
|
||||
});
|
||||
const userBalance = Number(response) || 0;
|
||||
setBalance(userBalance);
|
||||
return userBalance;
|
||||
} catch (error) {
|
||||
setBalance(0);
|
||||
return 0;
|
||||
} finally {
|
||||
setIsLoadingBalance(false);
|
||||
}
|
||||
},
|
||||
[setBalance]
|
||||
);
|
||||
|
||||
const balanceSetInterval = useCallback(
|
||||
(address: string, interval: number) => {
|
||||
try {
|
||||
if (balanceSetIntervalRef.current) {
|
||||
clearInterval(balanceSetIntervalRef.current);
|
||||
}
|
||||
|
||||
let isCalling = false;
|
||||
balanceSetIntervalRef.current = setInterval(async () => {
|
||||
if (isCalling) return;
|
||||
isCalling = true;
|
||||
await getBalance(address);
|
||||
isCalling = false;
|
||||
}, interval);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
[getBalance]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (authenticateOnMount) {
|
||||
authenticateUser();
|
||||
}
|
||||
if (userAccountInfo?.address && userAccountInfo?.publicKey) {
|
||||
authenticateUser(userAccountInfo);
|
||||
}
|
||||
}, [
|
||||
authenticateOnMount,
|
||||
authenticateUser,
|
||||
userAccountInfo?.address,
|
||||
userAccountInfo?.publicKey,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
address &&
|
||||
(balanceSetting?.onlyOnMount ||
|
||||
(balanceSetting?.interval && !isNaN(balanceSetting?.interval)))
|
||||
) {
|
||||
getBalance(address);
|
||||
}
|
||||
if (
|
||||
address &&
|
||||
balanceSetting?.interval !== undefined &&
|
||||
!isNaN(balanceSetting.interval)
|
||||
) {
|
||||
balanceSetInterval(address, balanceSetting.interval);
|
||||
}
|
||||
}, [
|
||||
balanceSetting?.onlyOnMount,
|
||||
balanceSetting?.interval,
|
||||
address,
|
||||
getBalance,
|
||||
balanceSetInterval,
|
||||
]);
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
address,
|
||||
publicKey,
|
||||
name,
|
||||
avatarUrl,
|
||||
isLoadingUser,
|
||||
errorMessageLoadingUser: errorLoadingUser,
|
||||
authenticateUser,
|
||||
}),
|
||||
[
|
||||
address,
|
||||
publicKey,
|
||||
name,
|
||||
avatarUrl,
|
||||
isLoadingUser,
|
||||
errorLoadingUser,
|
||||
authenticateUser,
|
||||
]
|
||||
);
|
||||
};
|
@ -7,7 +7,6 @@ import { ReturnType } from "../components/ResourceList/ResourceListDisplay";
|
||||
import { useCacheStore } from "../state/cache";
|
||||
import { useMultiplePublishStore, usePublishStatusStore } from "../state/multiplePublish";
|
||||
import { ResourceToPublish } from "../types/qortalRequests/types";
|
||||
import { MultiplePublishError } from "../components/MultiPublish/MultiPublishDialog";
|
||||
|
||||
interface StoredPublish {
|
||||
qortalMetadata: QortalMetadata;
|
||||
|
@ -9,6 +9,8 @@ export { useAudioPlayerHotkeys } from './components/AudioPlayer/useAudioPlayerHo
|
||||
export { VideoPlayerParent as VideoPlayer } from './components/VideoPlayer/VideoPlayerParent';
|
||||
export { useListReturn } from './hooks/useListData';
|
||||
export { useAllResourceStatus } from './hooks/useAllResourceStatus';
|
||||
export { useQortBalance } from './hooks/useBalance';
|
||||
export { useAuth } from './hooks/useAuth';
|
||||
import './index.css'
|
||||
export { executeEvent, subscribeToEvent, unsubscribeFromEvent } from './utils/events';
|
||||
export { formatBytes, formatDuration } from './utils/numbers';
|
||||
|
@ -23,6 +23,7 @@ interface AuthState {
|
||||
setIsLoadingUser: (loading: boolean) => void;
|
||||
setIsLoadingBalance: (loading: boolean) => void;
|
||||
setErrorLoadingUser: (error: string | null) => void;
|
||||
setName: (name: string | null) => void;
|
||||
}
|
||||
|
||||
// ✅ Typed Zustand Store
|
||||
@ -43,4 +44,11 @@ export const useAuthStore = create<AuthState>((set) => ({
|
||||
setIsLoadingUser: (loading) => set({ isLoadingUser: loading }),
|
||||
setIsLoadingBalance: (loading) => set({ isLoadingInitialBalance: loading }),
|
||||
setErrorLoadingUser: (error) => set({ errorLoadingUser: error }),
|
||||
setName: (name) =>
|
||||
set({
|
||||
name,
|
||||
avatarUrl: !name
|
||||
? null
|
||||
: `/arbitrary/THUMBNAIL/${encodeURIComponent(name)}/qortal_avatar?async=true`,
|
||||
}),
|
||||
}));
|
||||
|
@ -1,4 +1,6 @@
|
||||
export const createAvatarLink = (qortalName: string)=> {
|
||||
export const createAvatarLink = (qortalName: string): string => {
|
||||
if (!qortalName?.trim()) return '';
|
||||
|
||||
return `/arbitrary/THUMBNAIL/${encodeURIComponent(qortalName)}/qortal_avatar?async=true`
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user