Skip to content
Snippets Groups Projects
layers.selectors.ts 2.54 KiB
Newer Older
/* eslint-disable no-magic-numbers */
import { createSelector } from '@reduxjs/toolkit';
import { rootSelector } from '@/redux/root/root.selectors';
import { currentModelIdSelector } from '@/redux/models/models.selectors';
export const layersSelector = createSelector(rootSelector, state => state.layers);

export const layersStateForCurrentModelSelector = createSelector(
  layersSelector,
  currentModelIdSelector,
  (state, currentModelId) => state[currentModelId],
);

export const layersActiveLayerSelector = createSelector(
  layersStateForCurrentModelSelector,
  state => state?.data?.activeLayer || null,
);

export const layersLoadingSelector = createSelector(
  layersStateForCurrentModelSelector,
  state => state?.loading,
export const layersVisibilityForCurrentModelSelector = createSelector(
  layersStateForCurrentModelSelector,
  state => state?.data?.layersVisibility || {},
);
export const layersForCurrentModelSelector = createSelector(
  layersStateForCurrentModelSelector,
  state => state?.data?.layers || [],

export const highestZIndexSelector = createSelector(layersForCurrentModelSelector, layers => {
  if (!layers || layers.length === 0) return 0;

  const getMaxZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
    items.length > 0 ? Math.max(...items.map(item => item.z || 0)) : 0;

  return layers.reduce((maxZ, layer) => {
    const textsMaxZ = getMaxZFromItems(Object.values(layer.texts));
    const rectsMaxZ = getMaxZFromItems(layer.rects);
    const ovalsMaxZ = getMaxZFromItems(layer.ovals);
    const linesMaxZ = getMaxZFromItems(layer.lines);
    const imagesMaxZ = getMaxZFromItems(Object.values(layer.images));

    const layerMaxZ = Math.max(textsMaxZ, rectsMaxZ, ovalsMaxZ, linesMaxZ, imagesMaxZ);

    return Math.max(maxZ, layerMaxZ);
  }, 0);
});

export const lowestZIndexSelector = createSelector(layersForCurrentModelSelector, layers => {
  if (!layers || layers.length === 0) return 0;

  const getMinZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
    items.length > 0 ? Math.min(...items.map(item => item.z || 0)) : 0;

  return layers.reduce((minZ, layer) => {
    const textsMinZ = getMinZFromItems(Object.values(layer.texts));
    const rectsMinZ = getMinZFromItems(layer.rects);
    const ovalsMinZ = getMinZFromItems(layer.ovals);
    const linesMinZ = getMinZFromItems(layer.lines);
    const imagesMinZ = getMinZFromItems(Object.values(layer.images));

    const layerMinZ = Math.min(textsMinZ, rectsMinZ, ovalsMinZ, linesMinZ, imagesMinZ);

    return Math.min(minZ, layerMinZ);
  }, 0);
});