20260628215623
This commit is contained in:
1 parent
51622a4b1a
commit
e687846eb4
68 files changed
+2234
-1591
No files matched your search
@@ -1,20 +1,8 @@
|
||||
import {
|
||||
createContext,
|
||||
ReactNode,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useRef,
|
||||
} from "react";
|
||||
import { createContext, ReactNode, useCallback, useContext, useEffect, useRef } from "react";
|
||||
import { toast } from "sonner-native";
|
||||
import { useUserStore, useFamilyStore } from "@/store";
|
||||
import { useChatStore } from "@/store/chat";
|
||||
import {
|
||||
ChatMessage,
|
||||
OnlineUser,
|
||||
SendChatPayload,
|
||||
normalizeChatMessage,
|
||||
} from "@/types/chat";
|
||||
import { ChatMessage, OnlineUser, SendChatPayload, normalizeChatMessage } from "@/types/chat";
|
||||
|
||||
const RECONNECT_BASE = 1000;
|
||||
const RECONNECT_MAX = 30000;
|
||||
@@ -212,11 +200,7 @@ function useChatWebSocketConnection(): ChatWebSocketValue {
|
||||
export function ChatWebSocketProvider({ children }: { children: ReactNode }) {
|
||||
const value = useChatWebSocketConnection();
|
||||
|
||||
return (
|
||||
<ChatWebSocketContext.Provider value={value}>
|
||||
{children}
|
||||
</ChatWebSocketContext.Provider>
|
||||
);
|
||||
return <ChatWebSocketContext.Provider value={value}>{children}</ChatWebSocketContext.Provider>;
|
||||
}
|
||||
|
||||
export function useChatWebSocket() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState, useCallback, useRef } from "react";
|
||||
import { useState, useCallback, useRef, useEffect } from "react";
|
||||
import { toast } from "sonner-native";
|
||||
|
||||
interface StopOptions {
|
||||
@@ -16,17 +16,39 @@ interface RunLoadingOptions {
|
||||
export function useLoading() {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const toastIdRef = useRef<string | number | null>(null);
|
||||
// 用 ref 跟踪当前的 toast ID,避免闭包过期
|
||||
const loadingRef = useRef(false);
|
||||
|
||||
// 组件卸载时确保 toast 也被关闭
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
const id = toastIdRef.current;
|
||||
if (id) {
|
||||
toast.dismiss(id);
|
||||
toastIdRef.current = null;
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const startLoading = useCallback((message: string = "加载中...") => {
|
||||
// 如果已有 loading 进行中,先关闭旧的 toast
|
||||
if (loadingRef.current && toastIdRef.current) {
|
||||
toast.dismiss(toastIdRef.current);
|
||||
}
|
||||
loadingRef.current = true;
|
||||
setIsLoading(true);
|
||||
const id = toast.loading(message);
|
||||
const id = toast.loading(message, { duration: Infinity });
|
||||
toastIdRef.current = id;
|
||||
return id;
|
||||
}, []);
|
||||
|
||||
const stopLoading = useCallback((options?: StopOptions) => {
|
||||
setIsLoading(false);
|
||||
const id = toastIdRef.current;
|
||||
// 先关闭遮罩
|
||||
loadingRef.current = false;
|
||||
setIsLoading(false);
|
||||
toastIdRef.current = null;
|
||||
|
||||
if (id) {
|
||||
if (options?.type === "success") {
|
||||
toast.success(options.message || "操作成功", { id });
|
||||
@@ -35,16 +57,15 @@ export function useLoading() {
|
||||
} else {
|
||||
toast.dismiss(id);
|
||||
}
|
||||
toastIdRef.current = null;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const withLoading = useCallback(
|
||||
async <T,>(
|
||||
async <T>(
|
||||
promise: Promise<T>,
|
||||
loadingMessage: string = "加载中...",
|
||||
successMessage?: string,
|
||||
errorMessage?: string
|
||||
errorMessage?: string,
|
||||
): Promise<T> => {
|
||||
startLoading(loadingMessage);
|
||||
try {
|
||||
@@ -56,12 +77,12 @@ export function useLoading() {
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[startLoading, stopLoading]
|
||||
[startLoading, stopLoading],
|
||||
);
|
||||
|
||||
const runWithLoading = useCallback(
|
||||
async <T,>(task: () => Promise<T>, options?: RunLoadingOptions): Promise<T | undefined> => {
|
||||
if (isLoading) return undefined;
|
||||
async <T>(task: () => Promise<T>, options?: RunLoadingOptions): Promise<T | undefined> => {
|
||||
if (loadingRef.current) return undefined;
|
||||
|
||||
startLoading(options?.loadingMessage || "加载中...");
|
||||
try {
|
||||
@@ -77,7 +98,7 @@ export function useLoading() {
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[isLoading, startLoading, stopLoading],
|
||||
[startLoading, stopLoading],
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -94,7 +115,7 @@ export function useListLoading() {
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const [loadingMore, setLoadingMore] = useState(false);
|
||||
|
||||
const runInitial = useCallback(async <T,>(task: () => Promise<T>) => {
|
||||
const runInitial = useCallback(async <T>(task: () => Promise<T>) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
return await task();
|
||||
@@ -103,7 +124,7 @@ export function useListLoading() {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const runRefresh = useCallback(async <T,>(task: () => Promise<T>) => {
|
||||
const runRefresh = useCallback(async <T>(task: () => Promise<T>) => {
|
||||
setRefreshing(true);
|
||||
try {
|
||||
return await task();
|
||||
@@ -112,7 +133,7 @@ export function useListLoading() {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const runLoadMore = useCallback(async <T,>(task: () => Promise<T>) => {
|
||||
const runLoadMore = useCallback(async <T>(task: () => Promise<T>) => {
|
||||
setLoadingMore(true);
|
||||
try {
|
||||
return await task();
|
||||
|
||||
Reference in new issue
Block a user