5180 fichiers 38.5 Mo 0 téléchargements 255 vues mis à jour il y a 5 heures ui
nitro-v36-with-renderer-v36 / src / hooks / navigator / navigatorRoomInfoPopupStore.ts
navigatorRoomInfoPopupStore.ts 2.6 Ko Télécharger le fichier
import { RoomDataParser } from '@octane/renderer';
import { createOctaneStore } from '../../state/createOctaneStore';

export type NavigatorRoomInfoAnchorKind = 'info' | 'row' | 'tile';

const POPUP_HIDE_DELAY_MS = 4000;

export type NavigatorRoomInfoPopupState = {
    room: RoomDataParser | null;
    visible: boolean;
    x: number;
    y: number;
    hovered: boolean;
};

export type NavigatorRoomInfoPopupActions = {
    hide(): void;
    setHovered(hovered: boolean): void;
    toggleFromInfo(room: RoomDataParser, rect: DOMRect): void;
    retargetIfVisible(room: RoomDataParser, kind: NavigatorRoomInfoAnchorKind, rect: DOMRect): void;
};

const hideTimer = { id: 0, hideAt: 0 };

const clearHideTimer = () => {
    if (hideTimer.id) window.clearInterval(hideTimer.id);
    hideTimer.id = 0;
};

const armHideTimer = () => {
    hideTimer.hideAt = Date.now() + POPUP_HIDE_DELAY_MS;
    if (hideTimer.id) return;

    hideTimer.id = window.setInterval(() => {
        const state = useNavigatorRoomInfoPopupStore.getState();
        if (!state.visible) {
            clearHideTimer();
            return;
        }
        if (Date.now() < hideTimer.hideAt) return;
        if (state.hovered) return;
        state.hide();
    }, 250);
};

const anchorPoint = (kind: NavigatorRoomInfoAnchorKind, rect: DOMRect) => {
    const midY = rect.top + rect.height / 2;

    if (kind === 'tile') return { x: rect.right - 6, y: midY + 56 };
    if (kind === 'row') return { x: rect.right + 20, y: midY };

    return { x: rect.right, y: midY };
};

export const useNavigatorRoomInfoPopupStore = createOctaneStore<NavigatorRoomInfoPopupState & NavigatorRoomInfoPopupActions>()((set, get) => ({
    room: null,
    visible: false,
    x: 0,
    y: 0,
    hovered: false,

    hide: () => {
        clearHideTimer();
        set({ visible: false, room: null, hovered: false });
    },

    setHovered: (hovered) => {
        set({ hovered });
        if (hovered) hideTimer.hideAt = Date.now() + POPUP_HIDE_DELAY_MS;
    },

    toggleFromInfo: (room, rect) => {
        const current = get();
        if (current.visible) {
            current.hide();
            return;
        }

        const point = anchorPoint('info', rect);
        armHideTimer();
        set({
            room,
            visible: true,
            hovered: false,
            x: point.x,
            y: point.y
        });
    },

    retargetIfVisible: (room, kind, rect) => {
        if (!get().visible) return;

        const point = anchorPoint(kind, rect);
        armHideTimer();
        set({
            room,
            visible: true,
            x: point.x,
            y: point.y
        });
    }
}));
15Sujets
1Dépôts
20Membres
2En ligne
Profile
Inscrit
Dernière visite
Messages
0
Votes positifs
0
Votes négatifs
0

Nous utilisons des cookies pour assurer le bon fonctionnement du site et améliorer votre expérience. en savoir plus

Autoriser