2026-09-20 00:15:18 +03:00
|
|
|
import { useEffect, useState } from 'react';
|
2026-09-19 21:50:06 +03:00
|
|
|
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
|
|
|
|
|
|
|
|
import { fetchInstance, instanceQueryKey } from '@/api/instance';
|
|
|
|
|
import { fetchCurrentUser, currentUserQueryKey } from '@/api/users';
|
|
|
|
|
import type { InstanceInfo, User } from '@/api/types';
|
|
|
|
|
|
|
|
|
|
/** Текущий пользователь: единственный источник правды о сессии (cookie). */
|
|
|
|
|
export function useCurrentUser(): UseQueryResult<User> {
|
|
|
|
|
return useQuery({
|
|
|
|
|
queryKey: currentUserQueryKey,
|
|
|
|
|
queryFn: ({ signal }) => fetchCurrentUser(signal),
|
|
|
|
|
retry: false,
|
|
|
|
|
staleTime: 30_000,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function useInstance(): UseQueryResult<InstanceInfo> {
|
|
|
|
|
return useQuery({
|
|
|
|
|
queryKey: instanceQueryKey,
|
|
|
|
|
queryFn: ({ signal }) => fetchInstance(signal),
|
|
|
|
|
staleTime: 60_000,
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-09-20 00:15:18 +03:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Активно ли окно: вкладка видима и окно в фокусе.
|
|
|
|
|
*
|
|
|
|
|
* Нужен для отметки прочтения — `POST /ack` уходит только когда пользователь
|
|
|
|
|
* действительно смотрит на комнату.
|
|
|
|
|
*/
|
|
|
|
|
export function useWindowActive(): boolean {
|
|
|
|
|
const [active, setActive] = useState(
|
|
|
|
|
() => typeof document === 'undefined' || document.visibilityState !== 'hidden',
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const onFocus = (): void => setActive(true);
|
|
|
|
|
const onBlur = (): void => setActive(false);
|
|
|
|
|
const onVisibility = (): void => setActive(document.visibilityState !== 'hidden');
|
|
|
|
|
window.addEventListener('focus', onFocus);
|
|
|
|
|
window.addEventListener('blur', onBlur);
|
|
|
|
|
document.addEventListener('visibilitychange', onVisibility);
|
|
|
|
|
return () => {
|
|
|
|
|
window.removeEventListener('focus', onFocus);
|
|
|
|
|
window.removeEventListener('blur', onBlur);
|
|
|
|
|
document.removeEventListener('visibilitychange', onVisibility);
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
return active;
|
|
|
|
|
}
|