5180 fichiers 38.5 Mo 0 téléchargements 376 vues mis à jour il y a 7 heures ui
nitro-v36-with-renderer-v36 / src / components / room / widgets / chat / chatBubbleMetrics.ts
chatBubbleMetrics.ts 2.6 Ko Télécharger le fichier
export const DEFAULT_BUBBLE_STACK_OVERLAP = 4;

export interface BubbleVisualOffsets {
    top: number;
    bottom: number;
}

const EMPTY_OFFSETS: BubbleVisualOffsets = { top: 0, bottom: 0 };

const parseLengths = (value: string): number[] =>
    (value || '')
        .trim()
        .split(/\s+/)
        .filter((token) => token.length > 0)
        // A unitless outset is a multiple of `border-width`, which is 0 on every bubble, so it never paints outside the box.
        .map((token) => (token.endsWith('px') ? parseFloat(token) || 0 : 0));

export const getBorderImageOutsetEdges = (value: string): BubbleVisualOffsets => {
    const lengths = parseLengths(value);

    if (!lengths.length) return EMPTY_OFFSETS;

    return { top: lengths[0], bottom: lengths.length >= 3 ? lengths[2] : lengths[0] };
};

export const measureBubbleVisualOffsets = (element: HTMLElement): BubbleVisualOffsets => {
    if (!element) return EMPTY_OFFSETS;

    const bubble = element.querySelector<HTMLElement>('.chat-bubble') || element;
    const view = element.ownerDocument?.defaultView;

    let { top, bottom } = view ? getBorderImageOutsetEdges(view.getComputedStyle(bubble).borderImageOutset) : EMPTY_OFFSETS;

    const pointer = element.querySelector<HTMLElement>('.pointer');

    if (pointer) {
        const elementRect = element.getBoundingClientRect();
        const pointerRect = pointer.getBoundingClientRect();

        top = Math.max(top, elementRect.top - pointerRect.top);
        bottom = Math.max(bottom, pointerRect.bottom - elementRect.bottom);
    }

    return { top: Math.max(0, top), bottom: Math.max(0, bottom) };
};

export const getBubbleStackOverflowBottom = (visualOffsetBottom: number, overlap: number): number => {
    const paintedBelow = Number.isFinite(visualOffsetBottom) ? Math.max(0, visualOffsetBottom) : 0;
    const allowance = Number.isFinite(overlap) ? Math.max(0, overlap) : DEFAULT_BUBBLE_STACK_OVERLAP;

    return Math.max(0, paintedBelow - allowance);
};

interface PointerCandidate {
    id: number;
    senderId: number;
}

export const getPointerChatIds = (chats: readonly PointerCandidate[]): Set<number> => {
    const newestBySender = new Map<number, number>();
    const pointerIds = new Set<number>();

    chats.forEach((chat) => {
        if (chat.senderId < 0) {
            pointerIds.add(chat.id);

            return;
        }

        const newestId = newestBySender.get(chat.senderId);

        if (newestId === undefined || chat.id > newestId) newestBySender.set(chat.senderId, chat.id);
    });

    newestBySender.forEach((id) => pointerIds.add(id));

    return pointerIds;
};
15Sujets
1Dépôts
20Membres
3En 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