{
  "version": 3,
  "sources": ["../../card/image_card.tsx"],
  "sourcesContent": ["import * as React from \"react\"\nimport {observer} from \"mobx-react\"\nimport {classNames} from \"@cling/lib.web.utils\"\nimport {\n    CardColor,\n    BlobUID,\n    Card as CardModel,\n    CardUID,\n    MediaTranscodeStatus,\n    is_BlobUID,\n    ImageCardDisplay,\n    ImageCardDisplayKind,\n} from \"@cling/lib.shared.model\"\nimport {i18n} from \"@cling/lib.web.i18n\"\nimport {media_info_resource} from \"@cling/lib.web.resources\"\nimport {ui_actions, ui_state} from \"../state/index\"\nimport {is_provisional_thumbnail_url, thumbnail_url} from \"@cling/lib.web.resources/thumbnails\"\nimport {LoadingIndicator} from \"@cling/lib.web.lazy_load/loading_indicator\"\nimport {simple_tooltip_event_handlers} from \"@cling/lib.web.mdc/simple_tooltip\"\n\n/**\n * We strive for cards to reach this aspect ratio.\n * This is 3:2.\n */\nconst MAX_CARD_ASPECT_RATIO = 0.66\n\n/**\n * Up until this aspect ratio images are displayed in `cover` mode even if this means that we\n * loose some image information at the top and the bottom.\n * This is ok, as it results in the most pleasant experience and others (namely Google Photos)\n * do the same.\n * This is 16:9.\n */\nconst MAX_COVER_ASPECT_RATIO = 0.77\n\nconst loading = (\n    <div className=\"image-card__loading\" data-test-thumbnail-state=\"waiting\">\n        <LoadingIndicator delay={2000} />\n    </div>\n)\n\nconst broken = (\n    <div className=\"image-card__broken\">\n        <div className=\"image-card__broken-icon\" />\n    </div>\n)\n\nexport const ImageCard = observer(\n    ({\n        blob_uid_or_style,\n        card,\n        title,\n        title_display,\n        onClick,\n        className,\n        display,\n        playable_media,\n    }: {\n        blob_uid_or_style: BlobUID | React.CSSProperties\n        card: CardModel\n        title?: any\n        title_display?: \"cinema\" | \"banner\"\n        onClick?: React.MouseEventHandler<HTMLElement>\n        className?: string\n        display: ImageCardDisplay\n        playable_media?: boolean\n    }) => {\n        const dimension_elm = React.useRef<HTMLDivElement>(null)\n        const [image_dim, set_image_dim] = React.useState<{\n            width: number\n            height: number\n            playable_media: boolean\n        }>()\n        const blob_uid = is_BlobUID(blob_uid_or_style) ? blob_uid_or_style : undefined\n        const media_info = blob_uid ? media_info_resource.read(blob_uid) : undefined\n        React.useEffect(() => {\n            if (blob_uid) {\n                if (media_info) {\n                    set_image_dim({\n                        width: media_info.width,\n                        height: media_info.height,\n                        playable_media: !!media_info.transcode_status,\n                    })\n                }\n            } else {\n                set_image_dim({width: 128, height: 128, playable_media: false})\n            }\n        }, [blob_uid, media_info])\n        let padding_top\n        let background_size: \"cover\" | \"contain\"\n        let thumbnail_width\n        let thumbnail_height\n        if (!dimension_elm.current || !image_dim) {\n            padding_top = \"50%\"\n            background_size = \"cover\"\n            thumbnail_width = 0\n            thumbnail_height = 0\n        } else {\n            const card_width = dimension_elm.current.getBoundingClientRect().width\n            const {width: image_width, height: image_height} = image_dim\n            const device_pixel_ratio = Math.min(window.devicePixelRatio || 1, 3)\n            thumbnail_width = Math.min(image_width, Math.round(card_width * device_pixel_ratio))\n            thumbnail_height =\n                display.kind === ImageCardDisplayKind.banner\n                    ? 512\n                    : Math.min(\n                          image_height,\n                          Math.round(card_width * device_pixel_ratio * MAX_CARD_ASPECT_RATIO),\n                      )\n            const img_aspect_ratio =\n                display.kind === ImageCardDisplayKind.cinema && display.cinema_forced_aspect_ratio\n                    ? display.cinema_forced_aspect_ratio\n                    : image_height / image_width\n            const card_aspect_ratio = Math.min(img_aspect_ratio, MAX_CARD_ASPECT_RATIO)\n            padding_top = card_aspect_ratio * 100 + \"%\"\n            if (display.is_pattern) {\n                background_size = \"contain\"\n            } else {\n                if (\n                    !image_dim.playable_media &&\n                    display.kind !== ImageCardDisplayKind.banner &&\n                    img_aspect_ratio >= MAX_COVER_ASPECT_RATIO\n                ) {\n                    // Image is in \"portrait\" mode - i.e. it is much taller than wide.\n                    background_size = \"contain\"\n                } else {\n                    // Image almost or perfectly fits the card - i.e. has (almost) the same\n                    // aspect ratio or it is a video.\n                    background_size = \"cover\"\n                }\n            }\n        }\n        const show_more = React.useCallback(\n            (e: React.SyntheticEvent) => {\n                e.stopPropagation()\n                e.preventDefault()\n                ui_actions.toggle_content_collapsed(card)\n            },\n            [card],\n        )\n        const condensed = ui_state.is_content_collapsed(card)\n        return (\n            <div\n                className={classNames(\"image-card\", className, {\n                    \"image-card--condensed\": condensed,\n                    \"image-card--banner\": display.kind === ImageCardDisplayKind.banner,\n                    \"image-card--cinema\": display.kind === ImageCardDisplayKind.cinema,\n                })}\n                ref={dimension_elm}\n                data-test-id=\"ImageCard\"\n            >\n                <div style={{paddingTop: padding_top}}>\n                    {playable_media && <div className=\"image-card__play\" onClick={onClick}></div>}\n                    <AsyncThumbnail\n                        card={card}\n                        blob_uid_or_style={blob_uid_or_style}\n                        onClick={onClick}\n                        thumbnail_width={thumbnail_width}\n                        thumbnail_height={thumbnail_height}\n                        background_size={background_size}\n                        background_repeat={display.is_pattern ? \"repeat\" : \"no-repeat\"}\n                        background_color={display.background_color}\n                    />\n                </div>\n                {title && (\n                    <div\n                        onClick={onClick}\n                        className={classNames(\"image-card__title\", {\n                            \"image-card__title--cinema\":\n                                !title_display || title_display === \"cinema\",\n                            \"image-card__title--banner\": title_display === \"banner\",\n                            \"image-card__title--with-color\": card.color !== CardColor.no_color,\n                        })}\n                    >\n                        {title}\n                    </div>\n                )}\n                {condensed && (\n                    <div className=\"action image-card__more\" onClick={show_more}>\n                        {i18n.more_expand}\n                    </div>\n                )}\n            </div>\n        )\n    },\n)\n\nexport const AsyncThumbnail = observer(\n    ({\n        blob_uid_or_style,\n        card,\n        onClick,\n        thumbnail_height,\n        thumbnail_width,\n        background_size,\n        background_repeat,\n        background_color,\n    }: {\n        blob_uid_or_style: BlobUID | React.CSSProperties\n        card?: {uid: CardUID; color: CardColor}\n        onClick?: React.MouseEventHandler<HTMLElement>\n        thumbnail_width: number\n        thumbnail_height: number\n        background_size: \"cover\" | \"contain\"\n        background_repeat?: \"no-repeat\" | \"repeat\"\n        background_color?: string\n    }) => {\n        const [prev_url, set_prev_url] = React.useState(\"\")\n        const [url, set_url] = React.useState(\"\")\n        const [is_provisional_thumbnail, set_is_provisional_thumbnail] = React.useState(false)\n        const blob_uid = is_BlobUID(blob_uid_or_style) ? blob_uid_or_style : undefined\n        let style: React.CSSProperties\n        if (blob_uid) {\n            const media_info = media_info_resource.read(blob_uid)\n            if (media_info?.invalid) {\n                return broken\n            }\n            if (!media_info || media_info.transcode_status === MediaTranscodeStatus.in_progress) {\n                return loading\n            }\n            if (thumbnail_width === 0 || thumbnail_height === 0) {\n                return loading\n            }\n            const new_url = thumbnail_url({\n                blob_uid,\n                width: thumbnail_width,\n                height: thumbnail_height,\n            })\n            if (prev_url && new_url !== prev_url && is_provisional_thumbnail) {\n                const img = new Image()\n                img.onload = () => {\n                    set_prev_url(new_url)\n                    set_url(new_url)\n                    set_is_provisional_thumbnail(is_provisional_thumbnail_url(new_url))\n                }\n                img.src = new_url\n            } else if (new_url !== prev_url) {\n                set_prev_url(new_url)\n                set_url(new_url)\n                set_is_provisional_thumbnail(is_provisional_thumbnail_url(new_url))\n            }\n            if (!url) {\n                return loading\n            }\n            style = {\n                backgroundImage: `url(${url})`,\n            }\n        } else {\n            style = blob_uid_or_style as React.CSSProperties\n        }\n        return (\n            <>\n                {background_size === \"contain\" && (\n                    <div className=\"image-card__portrait-background\" style={style} />\n                )}\n                <div\n                    onClick={onClick}\n                    data-blob-uid={blob_uid}\n                    className=\"image-card__img\"\n                    data-test-id=\"ImageCard_image\"\n                    data-test-thumbnail-state={is_provisional_thumbnail ? \"waiting\" : \"\"}\n                    style={{\n                        ...style,\n                        backgroundSize: background_size,\n                        backgroundRepeat: background_repeat,\n                        backgroundColor: background_color,\n                    }}\n                />\n                {card && card.color !== CardColor.no_color && (\n                    <div\n                        aria-label={i18n.card_color(card.color)}\n                        className={`image-card__card-color-marker card--color-${card.color}`}\n                        {...simple_tooltip_event_handlers}\n                    />\n                )}\n            </>\n        )\n    },\n)\n\nexport const ImageCardPreview = observer(\n    ({image_url, badge}: {image_url: string; badge?: string}) => {\n        return (\n            <div className=\"card-details image-card image-card-preview\">\n                <div>\n                    <div\n                        className=\"image-card__img image-card-preview__img\"\n                        style={{backgroundImage: `url(${image_url})`}}\n                    />\n                    {!!badge && <div className=\"image-card-preview__badge\">{badge}</div>}\n                </div>\n            </div>\n        )\n    },\n)\n"],
  "mappings": "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",
  "names": ["init_compat_module", "MAX_CARD_ASPECT_RATIO", "MAX_COVER_ASPECT_RATIO", "loading", "_", "LoadingIndicator", "broken", "ImageCard", "observer", "blob_uid_or_style", "card", "title", "title_display", "onClick", "className", "display", "playable_media", "dimension_elm", "A", "image_dim", "set_image_dim", "d", "blob_uid", "is_BlobUID", "media_info", "media_info_resource", "y", "padding_top", "background_size", "thumbnail_width", "thumbnail_height", "card_width", "image_width", "image_height", "device_pixel_ratio", "img_aspect_ratio", "show_more", "q", "e", "ui_actions", "condensed", "ui_state", "classNames", "AsyncThumbnail", "i18n", "background_repeat", "background_color", "prev_url", "set_prev_url", "url", "set_url", "is_provisional_thumbnail", "set_is_provisional_thumbnail", "style", "new_url", "thumbnail_url", "img", "is_provisional_thumbnail_url", "k", "simple_tooltip_event_handlers", "ImageCardPreview", "image_url", "badge"]
}