diff --git a/ui/v2.5/src/components/Galleries/GalleryCard.tsx b/ui/v2.5/src/components/Galleries/GalleryCard.tsx index 26b488a86..238310d1f 100644 --- a/ui/v2.5/src/components/Galleries/GalleryCard.tsx +++ b/ui/v2.5/src/components/Galleries/GalleryCard.tsx @@ -1,7 +1,7 @@ import { Button, ButtonGroup, OverlayTrigger, Tooltip } from "react-bootstrap"; -import React, { useEffect, useState } from "react"; +import React, { useState } from "react"; import * as GQL from "src/core/generated-graphql"; -import { GridCard, calculateCardWidth } from "../Shared/GridCard/GridCard"; +import { GridCard } from "../Shared/GridCard/GridCard"; import { HoverPopover } from "../Shared/HoverPopover"; import { Icon } from "../Shared/Icon"; import { SceneLink, TagLink } from "../Shared/TagLink"; @@ -12,7 +12,6 @@ import NavUtils from "src/utils/navigation"; import { RatingBanner } from "../Shared/RatingBanner"; import { faBox, faPlayCircle, faTag } from "@fortawesome/free-solid-svg-icons"; import { galleryTitle } from "src/core/galleries"; -import ScreenUtils from "src/utils/screen"; import { StudioOverlay } from "../Shared/GridCard/StudioOverlay"; import { GalleryPreviewScrubber } from "./GalleryPreviewScrubber"; import cx from "classnames"; @@ -56,7 +55,7 @@ export const GalleryPreview: React.FC = ({ interface IProps { gallery: GQL.SlimGalleryDataFragment; - containerWidth?: number; + cardWidth?: number; selecting?: boolean; selected?: boolean | undefined; zoomIndex?: number; @@ -65,37 +64,6 @@ interface IProps { export const GalleryCard: React.FC = (props) => { const history = useHistory(); - const [cardWidth, setCardWidth] = useState(); - - useEffect(() => { - if ( - !props.containerWidth || - props.zoomIndex === undefined || - ScreenUtils.isMobile() - ) - return; - - let zoomValue = props.zoomIndex; - let preferredCardWidth: number; - switch (zoomValue) { - case 0: - preferredCardWidth = 280; - break; - case 1: - preferredCardWidth = 340; - break; - case 2: - preferredCardWidth = 480; - break; - case 3: - preferredCardWidth = 640; - } - let fittedCardWidth = calculateCardWidth( - props.containerWidth, - preferredCardWidth! - ); - setCardWidth(fittedCardWidth); - }, [props.containerWidth, props.zoomIndex]); function maybeRenderScenePopoverButton() { if (props.gallery.scenes.length === 0) return; @@ -207,7 +175,7 @@ export const GalleryCard: React.FC = (props) => { void; } +const zoomWidths = [280, 340, 480, 640]; + export const GalleryCardGrid: React.FC = ({ galleries, selectedIds, zoomIndex, onSelectChange, }) => { - const [componentRef, { width }] = useContainerDimensions(); + const [componentRef, { width: containerWidth }] = useContainerDimensions(); + const cardWidth = useCardWidth(containerWidth, zoomIndex, zoomWidths); + return (
{galleries.map((gallery) => ( 0} diff --git a/ui/v2.5/src/components/Groups/GroupCard.tsx b/ui/v2.5/src/components/Groups/GroupCard.tsx index 7e61a9a31..f1d6089d0 100644 --- a/ui/v2.5/src/components/Groups/GroupCard.tsx +++ b/ui/v2.5/src/components/Groups/GroupCard.tsx @@ -1,7 +1,7 @@ -import React, { useEffect, useMemo, useState } from "react"; +import React, { useMemo } from "react"; import { Button, ButtonGroup } from "react-bootstrap"; import * as GQL from "src/core/generated-graphql"; -import { GridCard, calculateCardWidth } from "../Shared/GridCard/GridCard"; +import { GridCard } from "../Shared/GridCard/GridCard"; import { HoverPopover } from "../Shared/HoverPopover"; import { Icon } from "../Shared/Icon"; import { SceneLink, TagLink } from "../Shared/TagLink"; @@ -9,7 +9,6 @@ import { TruncatedText } from "../Shared/TruncatedText"; import { FormattedMessage } from "react-intl"; import { RatingBanner } from "../Shared/RatingBanner"; import { faPlayCircle, faTag } from "@fortawesome/free-solid-svg-icons"; -import ScreenUtils from "src/utils/screen"; import { RelatedGroupPopoverButton } from "./RelatedGroupPopover"; const Description: React.FC<{ @@ -37,7 +36,7 @@ const Description: React.FC<{ interface IProps { group: GQL.GroupDataFragment; - containerWidth?: number; + cardWidth?: number; sceneNumber?: number; selecting?: boolean; selected?: boolean; @@ -50,7 +49,7 @@ interface IProps { export const GroupCard: React.FC = ({ group, sceneNumber, - containerWidth, + cardWidth, selecting, selected, zoomIndex, @@ -58,8 +57,6 @@ export const GroupCard: React.FC = ({ fromGroupId, onMove, }) => { - const [cardWidth, setCardWidth] = useState(); - const groupDescription = useMemo(() => { if (!fromGroupId) { return undefined; @@ -72,32 +69,6 @@ export const GroupCard: React.FC = ({ return containingGroup?.description ?? undefined; }, [fromGroupId, group.containing_groups]); - useEffect(() => { - if (!containerWidth || zoomIndex === undefined || ScreenUtils.isMobile()) - return; - - let zoomValue = zoomIndex; - let preferredCardWidth: number; - switch (zoomValue) { - case 0: - preferredCardWidth = 210; - break; - case 1: - preferredCardWidth = 250; - break; - case 2: - preferredCardWidth = 300; - break; - case 3: - preferredCardWidth = 375; - } - let fittedCardWidth = calculateCardWidth( - containerWidth, - preferredCardWidth! - ); - setCardWidth(fittedCardWidth); - }, [containerWidth, zoomIndex]); - function maybeRenderScenesPopoverButton() { if (group.scenes.length === 0) return; diff --git a/ui/v2.5/src/components/Groups/GroupCardGrid.tsx b/ui/v2.5/src/components/Groups/GroupCardGrid.tsx index e09f02c87..b73919e64 100644 --- a/ui/v2.5/src/components/Groups/GroupCardGrid.tsx +++ b/ui/v2.5/src/components/Groups/GroupCardGrid.tsx @@ -1,7 +1,10 @@ import React from "react"; import * as GQL from "src/core/generated-graphql"; import { GroupCard } from "./GroupCard"; -import { useContainerDimensions } from "../Shared/GridCard/GridCard"; +import { + useCardWidth, + useContainerDimensions, +} from "../Shared/GridCard/GridCard"; interface IGroupCardGrid { groups: GQL.GroupDataFragment[]; @@ -12,6 +15,8 @@ interface IGroupCardGrid { onMove?: (srcIds: string[], targetId: string, after: boolean) => void; } +const zoomWidths = [210, 250, 300, 375]; + export const GroupCardGrid: React.FC = ({ groups, selectedIds, @@ -20,13 +25,15 @@ export const GroupCardGrid: React.FC = ({ fromGroupId, onMove, }) => { - const [componentRef, { width }] = useContainerDimensions(); + const [componentRef, { width: containerWidth }] = useContainerDimensions(); + const cardWidth = useCardWidth(containerWidth, zoomIndex, zoomWidths); + return (
{groups.map((p) => ( 0} diff --git a/ui/v2.5/src/components/Images/ImageCard.tsx b/ui/v2.5/src/components/Images/ImageCard.tsx index 02b7ae29d..d530b253e 100644 --- a/ui/v2.5/src/components/Images/ImageCard.tsx +++ b/ui/v2.5/src/components/Images/ImageCard.tsx @@ -1,4 +1,4 @@ -import React, { MouseEvent, useEffect, useMemo, useState } from "react"; +import React, { MouseEvent, useMemo } from "react"; import { Button, ButtonGroup } from "react-bootstrap"; import cx from "classnames"; import * as GQL from "src/core/generated-graphql"; @@ -7,10 +7,7 @@ import { GalleryLink, TagLink } from "src/components/Shared/TagLink"; import { HoverPopover } from "src/components/Shared/HoverPopover"; import { SweatDrops } from "src/components/Shared/SweatDrops"; import { PerformerPopoverButton } from "src/components/Shared/PerformerPopoverButton"; -import { - GridCard, - calculateCardWidth, -} from "src/components/Shared/GridCard/GridCard"; +import { GridCard } from "src/components/Shared/GridCard/GridCard"; import { RatingBanner } from "src/components/Shared/RatingBanner"; import { faBox, @@ -20,12 +17,11 @@ import { } from "@fortawesome/free-solid-svg-icons"; import { imageTitle } from "src/core/files"; import { TruncatedText } from "../Shared/TruncatedText"; -import ScreenUtils from "src/utils/screen"; import { StudioOverlay } from "../Shared/GridCard/StudioOverlay"; interface IImageCardProps { image: GQL.SlimImageDataFragment; - containerWidth?: number; + cardWidth?: number; selecting?: boolean; selected?: boolean | undefined; zoomIndex: number; @@ -36,38 +32,6 @@ interface IImageCardProps { export const ImageCard: React.FC = ( props: IImageCardProps ) => { - const [cardWidth, setCardWidth] = useState(); - - useEffect(() => { - if ( - !props.containerWidth || - props.zoomIndex === undefined || - ScreenUtils.isMobile() - ) - return; - - let zoomValue = props.zoomIndex; - let preferredCardWidth: number; - switch (zoomValue) { - case 0: - preferredCardWidth = 280; - break; - case 1: - preferredCardWidth = 340; - break; - case 2: - preferredCardWidth = 480; - break; - case 3: - preferredCardWidth = 640; - } - let fittedCardWidth = calculateCardWidth( - props.containerWidth, - preferredCardWidth! - ); - setCardWidth(fittedCardWidth); - }, [props.containerWidth, props.zoomIndex]); - const file = useMemo( () => props.image.visual_files.length > 0 @@ -196,7 +160,7 @@ export const ImageCard: React.FC = ( ) => void; } +const zoomWidths = [280, 340, 480, 640]; + export const ImageGridCard: React.FC = ({ images, selectedIds, @@ -18,13 +23,15 @@ export const ImageGridCard: React.FC = ({ onSelectChange, onPreview, }) => { - const [componentRef, { width }] = useContainerDimensions(); + const [componentRef, { width: containerWidth }] = useContainerDimensions(); + const cardWidth = useCardWidth(containerWidth, zoomIndex, zoomWidths); + return (
{images.map((image, index) => ( 0} diff --git a/ui/v2.5/src/components/Performers/PerformerCard.tsx b/ui/v2.5/src/components/Performers/PerformerCard.tsx index 28e08f78e..02e2a68fd 100644 --- a/ui/v2.5/src/components/Performers/PerformerCard.tsx +++ b/ui/v2.5/src/components/Performers/PerformerCard.tsx @@ -1,10 +1,10 @@ -import React, { useEffect, useState } from "react"; +import React from "react"; import { Link } from "react-router-dom"; import { useIntl } from "react-intl"; import * as GQL from "src/core/generated-graphql"; import NavUtils from "src/utils/navigation"; import TextUtils from "src/utils/text"; -import { GridCard, calculateCardWidth } from "../Shared/GridCard/GridCard"; +import { GridCard } from "../Shared/GridCard/GridCard"; import { CountryFlag } from "../Shared/CountryFlag"; import { SweatDrops } from "../Shared/SweatDrops"; import { HoverPopover } from "../Shared/HoverPopover"; @@ -21,7 +21,6 @@ import { faTag } from "@fortawesome/free-solid-svg-icons"; import { RatingBanner } from "../Shared/RatingBanner"; import { usePerformerUpdate } from "src/core/StashService"; import { ILabeledId } from "src/models/list-filter/types"; -import ScreenUtils from "src/utils/screen"; import { FavoriteIcon } from "../Shared/FavoriteIcon"; import { PatchComponent } from "src/patch"; @@ -35,7 +34,7 @@ export interface IPerformerCardExtraCriteria { interface IPerformerCardProps { performer: GQL.PerformerDataFragment; - containerWidth?: number; + cardWidth?: number; ageFromDate?: string; selecting?: boolean; selected?: boolean; @@ -300,41 +299,13 @@ export const PerformerCard: React.FC = PatchComponent( (props) => { const { performer, - containerWidth, + cardWidth, selecting, selected, onSelectedChanged, zoomIndex, } = props; - const [cardWidth, setCardWidth] = useState(); - - useEffect(() => { - if (!containerWidth || zoomIndex === undefined || ScreenUtils.isMobile()) - return; - - let zoomValue = zoomIndex; - let preferredCardWidth: number; - switch (zoomValue) { - case 0: - preferredCardWidth = 240; - break; - case 1: - preferredCardWidth = 300; - break; - case 2: - preferredCardWidth = 375; - break; - case 3: - preferredCardWidth = 470; - } - let fittedCardWidth = calculateCardWidth( - containerWidth, - preferredCardWidth! - ); - setCardWidth(fittedCardWidth); - }, [containerWidth, zoomIndex]); - return ( = ({ performers, selectedIds, @@ -18,13 +23,15 @@ export const PerformerCardGrid: React.FC = ({ onSelectChange, extraCriteria, }) => { - const [componentRef, { width }] = useContainerDimensions(); + const [componentRef, { width: containerWidth }] = useContainerDimensions(); + const cardWidth = useCardWidth(containerWidth, zoomIndex, zoomWidths); + return (
{performers.map((p) => ( 0} diff --git a/ui/v2.5/src/components/Scenes/SceneCard.tsx b/ui/v2.5/src/components/Scenes/SceneCard.tsx index af7237264..99b910f67 100644 --- a/ui/v2.5/src/components/Scenes/SceneCard.tsx +++ b/ui/v2.5/src/components/Scenes/SceneCard.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useRef, useState } from "react"; +import React, { useEffect, useMemo, useRef } from "react"; import { Button, ButtonGroup, OverlayTrigger, Tooltip } from "react-bootstrap"; import { useHistory } from "react-router-dom"; import cx from "classnames"; @@ -13,7 +13,7 @@ import TextUtils from "src/utils/text"; import { SceneQueue } from "src/models/sceneQueue"; import { ConfigurationContext } from "src/hooks/Config"; import { PerformerPopoverButton } from "../Shared/PerformerPopoverButton"; -import { GridCard, calculateCardWidth } from "../Shared/GridCard/GridCard"; +import { GridCard } from "../Shared/GridCard/GridCard"; import { RatingBanner } from "../Shared/RatingBanner"; import { FormattedMessage } from "react-intl"; import { @@ -27,7 +27,6 @@ import { import { objectPath, objectTitle } from "src/core/files"; import { PreviewScrubber } from "./PreviewScrubber"; import { PatchComponent } from "src/patch"; -import ScreenUtils from "src/utils/screen"; import { StudioOverlay } from "../Shared/GridCard/StudioOverlay"; import { GroupTag } from "../Groups/GroupTag"; import { FileSize } from "../Shared/FileSize"; @@ -94,7 +93,7 @@ export const ScenePreview: React.FC = ({ interface ISceneCardProps { scene: GQL.SlimSceneDataFragment; - containerWidth?: number; + width?: number; previewHeight?: number; index?: number; queue?: SceneQueue; @@ -439,7 +438,6 @@ export const SceneCard = PatchComponent( "SceneCard", (props: ISceneCardProps) => { const { configuration } = React.useContext(ConfigurationContext); - const [cardWidth, setCardWidth] = useState(); const file = useMemo( () => (props.scene.files.length > 0 ? props.scene.files[0] : undefined), @@ -462,36 +460,6 @@ export const SceneCard = PatchComponent( return ""; } - useEffect(() => { - if ( - !props.containerWidth || - props.zoomIndex === undefined || - ScreenUtils.isMobile() - ) - return; - - let zoomValue = props.zoomIndex; - let preferredCardWidth: number; - switch (zoomValue) { - case 0: - preferredCardWidth = 280; - break; - case 1: - preferredCardWidth = 340; // this value is intentionally higher than 320 - break; - case 2: - preferredCardWidth = 480; - break; - case 3: - preferredCardWidth = 640; - } - let fittedCardWidth = calculateCardWidth( - props.containerWidth, - preferredCardWidth! - ); - setCardWidth(fittedCardWidth); - }, [props.containerWidth, props.zoomIndex]); - const cont = configuration?.interface.continuePlaylistDefault ?? false; const sceneLink = props.queue @@ -506,7 +474,7 @@ export const SceneCard = PatchComponent( className={`scene-card ${zoomIndex()} ${filelessClass()}`} url={sceneLink} title={objectTitle(props.scene)} - width={cardWidth} + width={props.width} linkClassName="scene-card-link" thumbnailSectionClassName="video-section" resumeTime={props.scene.resume_time ?? undefined} diff --git a/ui/v2.5/src/components/Scenes/SceneCardsGrid.tsx b/ui/v2.5/src/components/Scenes/SceneCardsGrid.tsx index 9884e37a0..03b907938 100644 --- a/ui/v2.5/src/components/Scenes/SceneCardsGrid.tsx +++ b/ui/v2.5/src/components/Scenes/SceneCardsGrid.tsx @@ -2,7 +2,10 @@ import React from "react"; import * as GQL from "src/core/generated-graphql"; import { SceneQueue } from "src/models/sceneQueue"; import { SceneCard } from "./SceneCard"; -import { useContainerDimensions } from "../Shared/GridCard/GridCard"; +import { + useCardWidth, + useContainerDimensions, +} from "../Shared/GridCard/GridCard"; interface ISceneCardsGrid { scenes: GQL.SlimSceneDataFragment[]; @@ -13,6 +16,8 @@ interface ISceneCardsGrid { fromGroupId?: string; } +const zoomWidths = [280, 340, 480, 640]; + export const SceneCardsGrid: React.FC = ({ scenes, queue, @@ -21,13 +26,16 @@ export const SceneCardsGrid: React.FC = ({ onSelectChange, fromGroupId, }) => { - const [componentRef, { width }] = useContainerDimensions(); + const [componentRef, { width: containerWidth }] = useContainerDimensions(); + + const cardWidth = useCardWidth(containerWidth, zoomIndex, zoomWidths); + return (
{scenes.map((scene, index) => ( { }; export const SceneMarkerCard = (props: ISceneMarkerCardProps) => { - const [cardWidth, setCardWidth] = useState(); - function zoomIndex() { if (!props.compact && props.zoomIndex !== undefined) { return `zoom-${props.zoomIndex}`; @@ -164,42 +161,12 @@ export const SceneMarkerCard = (props: ISceneMarkerCardProps) => { return ""; } - useEffect(() => { - if ( - !props.containerWidth || - props.zoomIndex === undefined || - ScreenUtils.isMobile() - ) - return; - - let zoomValue = props.zoomIndex; - let preferredCardWidth: number; - switch (zoomValue) { - case 0: - preferredCardWidth = 240; - break; - case 1: - preferredCardWidth = 340; // this value is intentionally higher than 320 - break; - case 2: - preferredCardWidth = 480; - break; - case 3: - preferredCardWidth = 640; - } - let fittedCardWidth = calculateCardWidth( - props.containerWidth, - preferredCardWidth! - ); - setCardWidth(fittedCardWidth); - }, [props, props.containerWidth, props.zoomIndex]); - return ( void; } +const zoomWidths = [240, 340, 480, 640]; + export const SceneMarkerCardsGrid: React.FC = ({ markers, selectedIds, zoomIndex, onSelectChange, }) => { - const [componentRef, { width }] = useContainerDimensions(); + const [componentRef, { width: containerWidth }] = useContainerDimensions(); + const cardWidth = useCardWidth(containerWidth, zoomIndex, zoomWidths); + return (
{markers.map((marker, index) => ( ( height: 0, }); - useResizeObserver(target, (entry) => { + const debouncedSetDimension = useDebounce((entry: ResizeObserverEntry) => { const { inlineSize: width, blockSize: height } = entry.contentBoxSize[0]; let difference = Math.abs(dimension.width - width); // Only adjust when width changed by a significant margin. This addresses the cornercase that sees @@ -73,11 +75,38 @@ export const useContainerDimensions = ( if (difference > sensitivityThreshold) { setDimension({ width, height }); } - }); + }, 50); + + useResizeObserver(target, debouncedSetDimension); return [target, dimension]; }; +export function useCardWidth( + containerWidth: number, + zoomIndex: number, + zoomWidths: number[] +) { + return useMemo(() => { + if ( + !containerWidth || + zoomIndex === undefined || + zoomIndex < 0 || + zoomIndex >= zoomWidths.length || + ScreenUtils.isMobile() + ) + return; + + let zoomValue = zoomIndex; + const preferredCardWidth = zoomWidths[zoomValue]; + let fittedCardWidth = calculateCardWidth( + containerWidth, + preferredCardWidth! + ); + return fittedCardWidth; + }, [containerWidth, zoomIndex, zoomWidths]); +} + const Checkbox: React.FC<{ selected?: boolean; onSelectedChanged?: (selected: boolean, shiftKey: boolean) => void; diff --git a/ui/v2.5/src/components/Studios/StudioCard.tsx b/ui/v2.5/src/components/Studios/StudioCard.tsx index 1d5b942c0..5cd1cc209 100644 --- a/ui/v2.5/src/components/Studios/StudioCard.tsx +++ b/ui/v2.5/src/components/Studios/StudioCard.tsx @@ -1,11 +1,8 @@ -import React, { useEffect, useState } from "react"; +import React from "react"; import { Link } from "react-router-dom"; import * as GQL from "src/core/generated-graphql"; import NavUtils from "src/utils/navigation"; -import { - GridCard, - calculateCardWidth, -} from "src/components/Shared/GridCard/GridCard"; +import { GridCard } from "src/components/Shared/GridCard/GridCard"; import { HoverPopover } from "../Shared/HoverPopover"; import { Icon } from "../Shared/Icon"; import { TagLink } from "../Shared/TagLink"; @@ -13,14 +10,13 @@ import { Button, ButtonGroup } from "react-bootstrap"; import { FormattedMessage } from "react-intl"; import { PopoverCountButton } from "../Shared/PopoverCountButton"; import { RatingBanner } from "../Shared/RatingBanner"; -import ScreenUtils from "src/utils/screen"; import { FavoriteIcon } from "../Shared/FavoriteIcon"; import { useStudioUpdate } from "src/core/StashService"; import { faTag } from "@fortawesome/free-solid-svg-icons"; interface IProps { studio: GQL.StudioDataFragment; - containerWidth?: number; + cardWidth?: number; hideParent?: boolean; selecting?: boolean; selected?: boolean; @@ -75,7 +71,7 @@ function maybeRenderChildren(studio: GQL.StudioDataFragment) { export const StudioCard: React.FC = ({ studio, - containerWidth, + cardWidth, hideParent, selecting, selected, @@ -83,34 +79,6 @@ export const StudioCard: React.FC = ({ onSelectedChanged, }) => { const [updateStudio] = useStudioUpdate(); - const [cardWidth, setCardWidth] = useState(); - - useEffect(() => { - if (!containerWidth || zoomIndex === undefined || ScreenUtils.isMobile()) - return; - - let zoomValue = zoomIndex; - console.log(zoomValue); - let preferredCardWidth: number; - switch (zoomValue) { - case 0: - preferredCardWidth = 280; - break; - case 1: - preferredCardWidth = 340; - break; - case 2: - preferredCardWidth = 420; - break; - case 3: - preferredCardWidth = 560; - } - let fittedCardWidth = calculateCardWidth( - containerWidth, - preferredCardWidth! - ); - setCardWidth(fittedCardWidth); - }, [containerWidth, zoomIndex]); function onToggleFavorite(v: boolean) { if (studio.id) { diff --git a/ui/v2.5/src/components/Studios/StudioCardGrid.tsx b/ui/v2.5/src/components/Studios/StudioCardGrid.tsx index b67166777..311d4e9d6 100644 --- a/ui/v2.5/src/components/Studios/StudioCardGrid.tsx +++ b/ui/v2.5/src/components/Studios/StudioCardGrid.tsx @@ -1,6 +1,9 @@ import React from "react"; import * as GQL from "src/core/generated-graphql"; -import { useContainerDimensions } from "../Shared/GridCard/GridCard"; +import { + useCardWidth, + useContainerDimensions, +} from "../Shared/GridCard/GridCard"; import { StudioCard } from "./StudioCard"; interface IStudioCardGrid { @@ -11,6 +14,8 @@ interface IStudioCardGrid { onSelectChange: (id: string, selected: boolean, shiftKey: boolean) => void; } +const zoomWidths = [280, 340, 420, 560]; + export const StudioCardGrid: React.FC = ({ studios, fromParent, @@ -18,13 +23,15 @@ export const StudioCardGrid: React.FC = ({ zoomIndex, onSelectChange, }) => { - const [componentRef, { width }] = useContainerDimensions(); + const [componentRef, { width: containerWidth }] = useContainerDimensions(); + const cardWidth = useCardWidth(containerWidth, zoomIndex, zoomWidths); + return (
{studios.map((studio) => ( = PatchComponent( ); export const TagCard: React.FC = PatchComponent("TagCard", (props) => { - const { - tag, - containerWidth, - zoomIndex, - selecting, - selected, - onSelectedChanged, - } = props; - const [cardWidth, setCardWidth] = useState(); - useEffect(() => { - if (!containerWidth || zoomIndex === undefined || ScreenUtils.isMobile()) - return; - - let zoomValue = zoomIndex; - let preferredCardWidth: number; - switch (zoomValue) { - case 0: - preferredCardWidth = 280; - break; - case 1: - preferredCardWidth = 340; - break; - case 2: - preferredCardWidth = 480; - break; - case 3: - preferredCardWidth = 640; - } - let fittedCardWidth = calculateCardWidth( - containerWidth, - preferredCardWidth! - ); - setCardWidth(fittedCardWidth); - }, [containerWidth, zoomIndex]); + const { tag, cardWidth, zoomIndex, selecting, selected, onSelectedChanged } = + props; return ( void; } +const zoomWidths = [280, 340, 480, 640]; + export const TagCardGrid: React.FC = ({ tags, selectedIds, zoomIndex, onSelectChange, }) => { - const [componentRef, { width }] = useContainerDimensions(); + const [componentRef, { width: containerWidth }] = useContainerDimensions(); + const cardWidth = useCardWidth(containerWidth, zoomIndex, zoomWidths); + return (
{tags.map((tag) => ( 0}