20260628215623

This commit is contained in:
oneao committed 2026-06-28 21:56:23 +08:00
1 parent 51622a4b1a
commit e687846eb4
68 files changed
+2234 -1591

No files matched your search

+3 -19
View File
@@ -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() {
+34 -13
View File
@@ -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();