fix and update
This commit is contained in:
102
apps/frontend/hooks/use-primary-family.ts
Normal file
102
apps/frontend/hooks/use-primary-family.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useFamilyOverlay } from '@/components/family/family-overlay-provider';
|
||||
import { useAuth } from '@/components/id/auth-provider';
|
||||
import {
|
||||
FamilyGroup,
|
||||
FamilyPresenceMember,
|
||||
fetchFamilyGroup,
|
||||
fetchFamilyGroups,
|
||||
fetchFamilyPresence
|
||||
} from '@/lib/api';
|
||||
|
||||
export function useSelectedFamily(enabled = true) {
|
||||
const { user, token, isPinLocked } = useAuth();
|
||||
const { selectedGroupId, setSelectedGroupId } = useFamilyOverlay();
|
||||
const [groups, setGroups] = useState<FamilyGroup[]>([]);
|
||||
const [group, setGroup] = useState<FamilyGroup | null>(null);
|
||||
const [presenceMembers, setPresenceMembers] = useState<FamilyPresenceMember[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
if (!enabled || !user || !token || isPinLocked) {
|
||||
setGroups([]);
|
||||
setGroup(null);
|
||||
setPresenceMembers([]);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const groupsResponse = await fetchFamilyGroups(user.id, token);
|
||||
const list = groupsResponse.groups ?? [];
|
||||
setGroups(list);
|
||||
|
||||
if (!list.length) {
|
||||
setGroup(null);
|
||||
setPresenceMembers([]);
|
||||
if (selectedGroupId) setSelectedGroupId(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const effectiveId =
|
||||
selectedGroupId && list.some((item) => item.id === selectedGroupId) ? selectedGroupId : list[0]!.id;
|
||||
|
||||
if (effectiveId !== selectedGroupId) {
|
||||
setSelectedGroupId(effectiveId);
|
||||
}
|
||||
|
||||
const [groupResponse, presenceResponse] = await Promise.all([
|
||||
fetchFamilyGroup(effectiveId, token),
|
||||
fetchFamilyPresence(effectiveId, token)
|
||||
]);
|
||||
setGroup(groupResponse);
|
||||
setPresenceMembers(presenceResponse.members ?? []);
|
||||
} catch {
|
||||
setGroups([]);
|
||||
setGroup(null);
|
||||
setPresenceMembers([]);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [enabled, isPinLocked, selectedGroupId, setSelectedGroupId, token, user]);
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
void refresh();
|
||||
}, [refresh]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled || !token || isPinLocked || !group) return;
|
||||
const timer = window.setInterval(() => void refresh(), 25_000);
|
||||
return () => window.clearInterval(timer);
|
||||
}, [enabled, group, isPinLocked, refresh, token]);
|
||||
|
||||
const presenceByUserId = useMemo(
|
||||
() => new Map(presenceMembers.map((member) => [member.userId, member])),
|
||||
[presenceMembers]
|
||||
);
|
||||
|
||||
const groupSummaries = useMemo(
|
||||
() => groups.map((item) => ({ id: item.id, name: item.name })),
|
||||
[groups]
|
||||
);
|
||||
|
||||
return {
|
||||
groups,
|
||||
groupSummaries,
|
||||
group,
|
||||
loading,
|
||||
hasFamily: Boolean(group),
|
||||
selectedGroupId: group?.id ?? selectedGroupId,
|
||||
setSelectedGroupId,
|
||||
presenceByUserId,
|
||||
refresh
|
||||
};
|
||||
}
|
||||
|
||||
/** @deprecated Используйте useSelectedFamily */
|
||||
export function usePrimaryFamily(enabled = true) {
|
||||
return useSelectedFamily(enabled);
|
||||
}
|
||||
Reference in New Issue
Block a user