UNPKG

@replyke/core

Version:

Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.

105 lines 4.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useUserActions = useUserActions; const react_1 = require("react"); const hooks_1 = require("../../store/hooks"); const userSlice_1 = require("../../store/slices/userSlice"); const userApi_1 = require("../../store/api/userApi"); /** * Redux-powered hook that provides current user management actions * Focused on current user operations only */ function useUserActions() { const dispatch = (0, hooks_1.useReplykeDispatch)(); // RTK Query mutations for current user const [updateUserMutation] = (0, userApi_1.useUpdateUserMutation)(); // User data management actions const handleSetUser = (0, react_1.useCallback)((user) => { // IMPORTANT: Validate that user has required data before setting // This prevents empty or partial user objects from being set to state if (user && !user.id) { console.warn('Attempted to set user without id - ignoring invalid user data'); return; } dispatch((0, userSlice_1.setUser)(user)); dispatch((0, userSlice_1.clearError)()); }, [dispatch]); const handleClearUser = (0, react_1.useCallback)(() => { dispatch((0, userSlice_1.clearUser)()); dispatch((0, userSlice_1.clearError)()); }, [dispatch]); // Update user with optimistic updates for instant UI feedback const updateUser = (0, react_1.useCallback)(async ({ projectId, userId, update, currentUser }) => { if (!projectId || !userId) { throw new Error("Project ID and User ID are required"); } dispatch((0, userSlice_1.setUpdating)(true)); dispatch((0, userSlice_1.clearError)()); // Store original user state for potential reversion const originalUser = currentUser; // Build optimistic update excluding fields that require server transformation: // - File uploads (avatar/banner as File) - we don't know the final URL // - Location - server transforms { latitude, longitude } to GeoJSON format const optimisticUpdate = {}; if (update.name !== undefined) optimisticUpdate.name = update.name; if (update.username !== undefined) optimisticUpdate.username = update.username; if (update.bio !== undefined) optimisticUpdate.bio = update.bio; if (update.birthdate !== undefined) optimisticUpdate.birthdate = update.birthdate; if (update.metadata !== undefined) optimisticUpdate.metadata = update.metadata; // Only apply avatar optimistically if it's a string URL (not a file upload) if (typeof update.avatar === 'string' || update.avatar === null) { optimisticUpdate.avatar = update.avatar; } // OPTIMISTIC UPDATE: Apply changes immediately for instant UI feedback if (Object.keys(optimisticUpdate).length > 0) { dispatch((0, userSlice_1.updateUserOptimistic)(optimisticUpdate)); } try { const result = await updateUserMutation({ projectId, userId, update }).unwrap(); // Replace optimistic update with real server data dispatch((0, userSlice_1.setUser)(result)); return result; } catch (error) { // REVERT OPTIMISTIC UPDATE: Restore original user state on API failure if (originalUser) { dispatch((0, userSlice_1.setUser)(originalUser)); } const errorMessage = error instanceof Error ? error.message : 'Failed to update user'; dispatch((0, userSlice_1.setError)(errorMessage)); throw error; } finally { dispatch((0, userSlice_1.setUpdating)(false)); } }, [updateUserMutation, dispatch]); // Removed other-user methods - use existing legacy hooks instead: // - useFetchUser // - useFetchUserByForeignId // - useCheckUsernameAvailability // - useFetchUserSuggestions // Error handling actions const clearUserError = (0, react_1.useCallback)(() => { dispatch((0, userSlice_1.clearError)()); }, [dispatch]); return { // Current user data management setUser: handleSetUser, clearUser: handleClearUser, // Current user operations updateUser, // Error handling clearError: clearUserError, }; } exports.default = useUserActions; //# sourceMappingURL=useUserActions.js.map