From de3ce6cbb2af791fd5ad1a618c4fe53f6063a7d0 Mon Sep 17 00:00:00 2001 From: Alexandra Goff Date: Tue, 28 Jan 2025 12:29:49 -0500 Subject: [PATCH] feat: document type asset pages --- .../collections/[gallery]/[asset]/page.tsx | 17 ++++-- .../atomic/Tile/patterns/SlideTile/styles.js | 6 +- components/atomic/Tile/styles.js | 9 ++- .../Callout/CalloutEntry/styles.js | 6 +- components/layout/SharePopup/index.js | 56 ----------------- components/layout/SharePopup/styles.js | 20 ------ components/molecules/SharePopup/index.tsx | 61 +++++++++++++++++++ .../molecules/SharePopup/styles.module.css | 33 ++++++++++ .../organisms/gallery/CantoDocument/index.tsx | 51 ++++++++++++++++ .../organisms/gallery/CantoDownload/index.tsx | 2 +- .../organisms/gallery/CantoFigure/index.tsx | 45 +++++++++++--- .../gallery/CantoFigure/styles.module.css | 9 +++ .../organisms/gallery/CantoImage/index.tsx | 8 +-- .../organisms/gallery/CantoVideo/index.tsx | 4 +- .../gallery/FilteredResults/index.tsx | 2 +- .../organisms/gallery/PreviewGrid/index.tsx | 3 +- .../gallery/metadata/Asset/index.tsx | 39 ++++++++++-- components/templates/GalleryPage/index.tsx | 2 +- lib/api/canto/metadata.ts | 7 ++- lib/api/galleries/index.ts | 15 +++-- lib/api/galleries/schema.ts | 13 ++-- lib/i18n/localeStrings/en/translation.json | 13 ++-- 22 files changed, 284 insertions(+), 137 deletions(-) delete mode 100644 components/layout/SharePopup/index.js delete mode 100644 components/layout/SharePopup/styles.js create mode 100644 components/molecules/SharePopup/index.tsx create mode 100644 components/molecules/SharePopup/styles.module.css create mode 100644 components/organisms/gallery/CantoDocument/index.tsx diff --git a/app/[locale]/gallery/collections/[gallery]/[asset]/page.tsx b/app/[locale]/gallery/collections/[gallery]/[asset]/page.tsx index 5e26df78..b73abfef 100644 --- a/app/[locale]/gallery/collections/[gallery]/[asset]/page.tsx +++ b/app/[locale]/gallery/collections/[gallery]/[asset]/page.tsx @@ -12,6 +12,7 @@ import ImageSizes from "@/components/organisms/gallery/metadata/Sizes"; import AssetTags from "@/components/organisms/gallery/metadata/Tags"; import CantoImage from "@/components/organisms/gallery/CantoImage"; import CantoVideo from "@/components/organisms/gallery/CantoVideo"; +import CantoDocument from "@/components/organisms/gallery/CantoDocument"; import AssetMetadata from "@/components/organisms/gallery/metadata/Asset"; export async function generateMetadata({ @@ -29,6 +30,7 @@ export async function generateMetadata({ const assetComponent: Record = { image: CantoImage, video: CantoVideo, + document: CantoDocument, }; const GalleryAsset: FunctionComponent = async ({ @@ -72,17 +74,21 @@ const GalleryAsset: FunctionComponent = async ({ image: ( <> ), video: , + document: ( + <> + + + ), }; const Asset = assetComponent[scheme]; + const dateCreated = new Date(DateCreated); return ( = async ({ parentUri, id, name, + scheme, + dateCreated, }} /> } metadataBlocks={ } metadataLinks={links[scheme]} diff --git a/components/atomic/Tile/patterns/SlideTile/styles.js b/components/atomic/Tile/patterns/SlideTile/styles.js index 796b3ba0..5f299a91 100644 --- a/components/atomic/Tile/patterns/SlideTile/styles.js +++ b/components/atomic/Tile/patterns/SlideTile/styles.js @@ -1,7 +1,7 @@ /* eslint-disable */ import styled from "styled-components"; import { MixedLink as BaseMixedLink } from "@rubin-epo/epo-react-lib"; -import SharePopupComponent from "@/layout/SharePopup"; +import SharePopupComponent from "@/components/molecules/SharePopup"; import { BREAK_PHABLET, BREAK_PHABLET_MIN, @@ -899,10 +899,12 @@ export const PlayButton = styled.span` `; export const SharePopup = styled(SharePopupComponent)` + --color-background-button: transparent; + --color-font-button: var(--neutral40); + position: absolute; inset-block-end: 30px; inset-inline-end: 30px; - color: var(--neutral40); @media (max-width: ${BREAK_TABLET}) { display: none; diff --git a/components/atomic/Tile/styles.js b/components/atomic/Tile/styles.js index ab5146cd..0baa0c15 100644 --- a/components/atomic/Tile/styles.js +++ b/components/atomic/Tile/styles.js @@ -2,7 +2,7 @@ import styled from "styled-components"; import BaseMixedLink from "@rubin-epo/epo-react-lib/MixedLink"; import BaseResponsiveImage from "@rubin-epo/epo-react-lib/ResponsiveImage"; -import SharePopupComponent from "@/layout/SharePopup"; +import SharePopupComponent from "@/components/molecules/SharePopup"; import { BREAK_PHABLET, BREAK_PHABLET_MIN, @@ -818,7 +818,7 @@ export const MixedLink = styled(BaseMixedLink)` } &.padded-bottom { - padding-bottom: 49px; + padding-bottom: calc(15px + var(--size-spacing-m)); @media (max-width: ${BREAK_TABLET}) { padding-bottom: 0; @@ -909,9 +909,8 @@ export const PlayButton = styled.span` export const SharePopup = styled(SharePopupComponent)` position: absolute; - right: 12px; - bottom: 0; - color: var(--neutral40); + inset-block-end: 15px; + inset-inline-end: 15px; @media (max-width: ${BREAK_TABLET}) { display: none; diff --git a/components/content-blocks/Callout/CalloutEntry/styles.js b/components/content-blocks/Callout/CalloutEntry/styles.js index 6502d651..ee38b020 100644 --- a/components/content-blocks/Callout/CalloutEntry/styles.js +++ b/components/content-blocks/Callout/CalloutEntry/styles.js @@ -1,6 +1,6 @@ import styled from "styled-components"; import { MixedLink } from "@rubin-epo/epo-react-lib"; -import SharePopupComponent from "@/layout/SharePopup"; +import SharePopupComponent from "@/components/molecules/SharePopup"; import { fluidScale, containerRegular, @@ -201,10 +201,12 @@ export const FooterButton = styled(MixedLink)` `; export const SharePopup = styled(SharePopupComponent)` + --color-background-button: transparent; + --color-font-button: var(--neutral40); + position: absolute; inset-block-end: 30px; inset-inline-end: 30px; - color: var(--neutral40); @media (max-width: ${tokens.BREAK_TABLET}) { display: none; diff --git a/components/layout/SharePopup/index.js b/components/layout/SharePopup/index.js deleted file mode 100644 index 1ef2787c..00000000 --- a/components/layout/SharePopup/index.js +++ /dev/null @@ -1,56 +0,0 @@ -"use client"; -import { useState } from "react"; -import PropTypes from "prop-types"; -import { Popover } from "@headlessui/react"; -import { usePopper } from "react-popper"; -import { useTranslation } from "react-i18next"; -import ShareButtons from "@/atomic/Share"; -import { IconComposer } from "@rubin-epo/epo-react-lib"; -import * as Styled from "./styles"; -import { isAbsoluteUrl } from "@/helpers"; - -const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL; - -function createFinalUrl(url) { - if (isAbsoluteUrl(url)) return url; - - const urlObj = new URL(url, BASE_URL); - return urlObj.toString(); -} - -function SharePopup({ title, url, className }) { - const { t } = useTranslation(); - - const [referenceElement, setReferenceElement] = useState(); - const [popperElement, setPopperElement] = useState(); - - const { styles, attributes } = usePopper(referenceElement, popperElement); - - return ( - - - - {t("share.label_item", { title })} - - - - - - - - ); -} - -SharePopup.displayName = "Layout.SharePopup"; - -SharePopup.propTypes = { - title: PropTypes.string.isRequired, - url: PropTypes.string.isRequired, - className: PropTypes.string, -}; - -export default SharePopup; diff --git a/components/layout/SharePopup/styles.js b/components/layout/SharePopup/styles.js deleted file mode 100644 index 4f93903e..00000000 --- a/components/layout/SharePopup/styles.js +++ /dev/null @@ -1,20 +0,0 @@ -import styled from "styled-components"; -import { Popover } from "@headlessui/react"; - -export const PanelInner = styled.div` - padding: 0.5em; - background-color: var(--white); - border-radius: 0.5em; - box-shadow: 5px 15px 35px 8px rgba(0, 0, 0, 13%); -`; - -export const Button = styled(Popover.Button)` - &:hover, - &.focus-visible, - &:focus-visible, - &[aria-expanded="true"] { - svg { - outline: 1px solid currentcolor; - } - } -`; diff --git a/components/molecules/SharePopup/index.tsx b/components/molecules/SharePopup/index.tsx new file mode 100644 index 00000000..efea5b7c --- /dev/null +++ b/components/molecules/SharePopup/index.tsx @@ -0,0 +1,61 @@ +"use client"; +import { FC, useState } from "react"; +import { Popover } from "@headlessui/react"; +import { usePopper } from "react-popper"; +import { useTranslation } from "react-i18next"; +import IconComposer from "@rubin-epo/epo-react-lib/IconComposer"; +import { isAbsoluteUrl } from "@/helpers"; +import ShareButtons from "@/atomic/Share"; +import styles from "./styles.module.css"; + +const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL; + +function createFinalUrl(url: string) { + if (isAbsoluteUrl(url)) return url; + + const urlObj = new URL(url, BASE_URL); + return urlObj.toString(); +} + +interface SharePopupProps { + title: string; + url: string; + className?: string; +} + +const SharePopup: FC = ({ title, url, className }) => { + const { t } = useTranslation(); + const [referenceElement, setReferenceElement] = + useState(null); + const [popperElement, setPopperElement] = useState( + null + ); + const { styles: popperStyles, attributes } = usePopper( + referenceElement, + popperElement, + { + modifiers: [{ name: "offset", options: { offset: [0, 10] } }], + } + ); + + return ( + + + + {t("share.label_item", { title })} + + + + + + ); +}; + +SharePopup.displayName = "Layout.SharePopup"; + +export default SharePopup; diff --git a/components/molecules/SharePopup/styles.module.css b/components/molecules/SharePopup/styles.module.css new file mode 100644 index 00000000..dcc39d2a --- /dev/null +++ b/components/molecules/SharePopup/styles.module.css @@ -0,0 +1,33 @@ +.button { + aspect-ratio: 1; + background-color: var( + --color-background-button, + var(--color-background-tile-light) + ); + border-radius: calc(var(--size-spacing-m) / 2); + border: 1px solid transparent; + box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 16%); + color: var(--color-font-button, #313333); + font-size: var(--size-spacing-m); + width: var(--size-spacing-m); + display: flex; + align-items: center; + justify-content: center; + + &:not(:disabled):hover, + &[data-headlessui-state="open"] { + border-color: var(--color-border-button-hover, #707070); + outline: none; + } + + &:focus-visible { + outline: none; + } +} + +.panel { + padding: var(--size-spacing-2xs); + background-color: var(--white); + border-radius: 5px; + box-shadow: 5px 15px 35px 8px rgba(0, 0, 0, 13%); +} diff --git a/components/organisms/gallery/CantoDocument/index.tsx b/components/organisms/gallery/CantoDocument/index.tsx new file mode 100644 index 00000000..10b06f60 --- /dev/null +++ b/components/organisms/gallery/CantoDocument/index.tsx @@ -0,0 +1,51 @@ +import { FC } from "react"; +import { DigitalDocument } from "schema-dts"; +import Image from "next/image"; +import StructuredData from "@/components/atomic/StructuredData"; +import { CantoAssetDetailed } from "@/lib/api/galleries/schema"; +import { assetAlt } from "@/lib/api/canto/metadata"; +import { tokens } from "@rubin-epo/epo-react-lib/styles"; +import { resizeCantoImage } from "@/lib/api/canto/resize"; + +interface CantoDocumentProps { + locale: string; + asset: CantoAssetDetailed; +} + +const CantoDocument: FC = ({ locale, asset }) => { + const { additional, url, width, height } = asset; + + const aspectRatio = width / height; + const landscapeSizes = `(max-width: ${tokens.BREAK_TABLET}) 100vw, 1435px`; + const portraitSizes = `(max-width: ${tokens.BREAK_TABLET}) 100vw, 700px`; + + const structuredData: DigitalDocument = { + "@type": "DigitalDocument", + size: asset.size, + url: url.directUrlOriginal, + creditText: asset.additional.Credit || undefined, + encodingFormat: asset.default.ContentType, + dateCreated: asset.default.DateCreated, + thumbnailUrl: resizeCantoImage(url.directUrlPreview, 100), + }; + + return ( + <> + + {assetAlt(additional, + + ); +}; + +CantoDocument.displayName = "Organism.Gallery.CantoDocument"; + +export default CantoDocument; diff --git a/components/organisms/gallery/CantoDownload/index.tsx b/components/organisms/gallery/CantoDownload/index.tsx index 066a52a3..3f23f6ee 100644 --- a/components/organisms/gallery/CantoDownload/index.tsx +++ b/components/organisms/gallery/CantoDownload/index.tsx @@ -19,7 +19,7 @@ const CantoDownload: FunctionComponent = async ({ diff --git a/components/organisms/gallery/CantoFigure/index.tsx b/components/organisms/gallery/CantoFigure/index.tsx index 17bdb776..4de45773 100644 --- a/components/organisms/gallery/CantoFigure/index.tsx +++ b/components/organisms/gallery/CantoFigure/index.tsx @@ -1,12 +1,16 @@ import { FunctionComponent, ReactNode } from "react"; import Figure from "@rubin-epo/epo-react-lib/Figure"; -import { CantoAssetAdditional } from "@/lib/api/galleries/schema"; -import { assetCaption } from "@/lib/api/canto/metadata"; +import { + CantoAssetAdditional, + CantoAssetScheme, +} from "@/lib/api/galleries/schema"; +import { assetCaption, assetTitle } from "@/lib/api/canto/metadata"; import { useTranslation } from "@/lib/i18n"; -import SharePopup from "@/components/layout/SharePopup"; +import SharePopup from "@/components/molecules/SharePopup"; import CantoDownload from "../CantoDownload"; import { CloseButton } from "./CantoFigure.client"; import styles from "./styles.module.css"; +import Stack from "@rubin-epo/epo-react-lib/Stack"; interface CantoFigureProps { locale: string; @@ -14,11 +18,13 @@ interface CantoFigureProps { additional: CantoAssetAdditional; downloadUrl: string; asset: ReactNode; - width: string; - height: string; + width: number; + height: number; id: string; parentUri: string; gallery: string; + scheme: CantoAssetScheme; + dateCreated: Date; } const CantoFigure: FunctionComponent = async ({ @@ -32,15 +38,34 @@ const CantoFigure: FunctionComponent = async ({ id, parentUri, gallery, + scheme, + dateCreated, }) => { const { t } = await useTranslation(locale); - const aspectRatio = parseInt(width) / parseInt(height); + const aspectRatio = width / height; + const shortestSide = Math.min(width, height); + const useHorizontalLayout = aspectRatio < 1 || shortestSide < 720; + + const additionalInfo = ( + <> +
{t(`gallery.${scheme}`)}
+
{assetTitle(additional, locale)}
+ + + ); + + const hasAdditionalInfo = scheme === "document"; return (
- {assetCaption(additional, locale)} + + {hasAdditionalInfo && additionalInfo} +
{assetCaption(additional, locale)}
{additional?.Credit && (
{t("gallery.credit", { @@ -52,9 +77,9 @@ const CantoFigure: FunctionComponent = async ({
- +
} - layout={aspectRatio < 1 ? "horizontal" : "vertical"} + layout={useHorizontalLayout ? "horizontal" : "vertical"} withBackground >
= ({ locale, asset }) => { - const { additional, url } = asset; + const { additional, url, width, height } = asset; - const width = parseInt(asset.width); - const height = parseInt(asset.height); const aspectRatio = width / height; const landscapeSizes = `(max-width: ${tokens.BREAK_TABLET}) 100vw, 1435px`; const portraitSizes = `(max-width: ${tokens.BREAK_TABLET}) 100vw, 700px`; @@ -28,8 +26,8 @@ const CantoImage: FunctionComponent = ({ locale, asset }) => { contentUrl: url.directUrlOriginal, creditText: asset.additional.Credit || undefined, encodingFormat: asset.default.ContentType, - height: asset.width, - width: asset.height, + height: `${width}px`, + width: `${height}px`, dateCreated: asset.default.DateCreated, thumbnail: { "@type": "ImageObject", diff --git a/components/organisms/gallery/CantoVideo/index.tsx b/components/organisms/gallery/CantoVideo/index.tsx index 694f4c7a..2e34364a 100644 --- a/components/organisms/gallery/CantoVideo/index.tsx +++ b/components/organisms/gallery/CantoVideo/index.tsx @@ -25,8 +25,8 @@ const CantoVideo: FunctionComponent = ({ locale, asset }) => { creditText: asset.additional.Credit || undefined, encodingFormat: asset.default.ContentType, dateCreated: asset.default.DateCreated, - height: asset.height, - width: asset.width, + height: `${width}px`, + width: `${height}px`, }; return ( diff --git a/components/organisms/gallery/FilteredResults/index.tsx b/components/organisms/gallery/FilteredResults/index.tsx index fe1acffd..e59f5c9c 100644 --- a/components/organisms/gallery/FilteredResults/index.tsx +++ b/components/organisms/gallery/FilteredResults/index.tsx @@ -56,7 +56,7 @@ const FilteredResults: FC = ({ total, filters }) => { break; case "type": displayValue = t("gallery.filters.type", { - type: t(`gallery.filters.${value}`).toLocaleLowerCase(language), + type: t(`gallery.${value}_other`).toLocaleLowerCase(language), }); break; } diff --git a/components/organisms/gallery/PreviewGrid/index.tsx b/components/organisms/gallery/PreviewGrid/index.tsx index 849b2b8d..4c75b408 100644 --- a/components/organisms/gallery/PreviewGrid/index.tsx +++ b/components/organisms/gallery/PreviewGrid/index.tsx @@ -79,9 +79,8 @@ const PreviewGridContent: FunctionComponent = async ({ className={styles.tile} > {assetAlt(additional,> = { + image: ["dateCreated", "size", "fileSize"], + video: ["dateCreated", "size", "fileSize"], + document: ["datePublished"], +}; + const AssetMetadata: FunctionComponent = async ({ width, height, @@ -27,8 +36,8 @@ const AssetMetadata: FunctionComponent = async ({ const { t } = await useTranslation(locale); const { quantity, unit } = convert(size, "bytes").to("best"); - const items: Array = [ - { + const metadata: Record = { + dateCreated: { key: t("gallery.date-created"), value: ( ), }, - { key: t("gallery.size"), value: `${width} × ${height} px` }, - { + datePublished: { + key: t("gallery.date-published"), + value: ( + + ), + }, + size: { key: t("gallery.size"), value: `${width} × ${height} px` }, + fileSize: { key: t("gallery.file-size"), value: `${new Intl.NumberFormat(locale, { maximumFractionDigits: 2, }).format(quantity)}${unit}`, }, - ]; + }; + + const items: Array = []; + + Object.entries(metadata).forEach(([key, value]) => { + if (metadataMap[scheme].includes(key)) { + items.push(value); + } + }); return ( > = async ({ const filterOptions = [ ...SupportedCantoScheme.options.map((value) => { - return { name: t(`gallery.filters.${value}`), query: "type", value }; + return { name: t(`gallery.${value}_other`, {}), query: "type", value }; }), ]; diff --git a/lib/api/canto/metadata.ts b/lib/api/canto/metadata.ts index 09f26f36..fe0ce3c4 100644 --- a/lib/api/canto/metadata.ts +++ b/lib/api/canto/metadata.ts @@ -63,6 +63,7 @@ export const assetToPageMetadata = ( additional, scheme, width, + height, url: { directUrlOriginal, directUrlPreviewPlay }, } = asset; @@ -71,8 +72,8 @@ export const assetToPageMetadata = ( players: { playerUrl: directUrlPreviewPlay || directUrlOriginal, streamUrl: directUrlPreviewPlay || directUrlOriginal, - width: parseInt(width), - height: parseInt(width), + width, + height, }, }; @@ -108,7 +109,7 @@ export const assetToOpenGraphImage = ( const baseAttributes = { url: directUrlPreview, alt, type: "image/jpeg" }; if (width && height) { - const aspectRatio = parseInt(width) / parseInt(height); + const aspectRatio = width / height; const previewSize = getPreviewSize(directUrlPreview); if (aspectRatio < 1) { diff --git a/lib/api/galleries/index.ts b/lib/api/galleries/index.ts index 37d84eff..405e5cc4 100644 --- a/lib/api/galleries/index.ts +++ b/lib/api/galleries/index.ts @@ -5,8 +5,8 @@ import { CantoAssetMetadata, GalleryDataFilters, MetadataAssetSchema, - SupportedCantoScheme, UnsupportedCantoScheme, + SupportedCantoScheme, } from "./schema"; import z from "zod"; import { @@ -42,16 +42,21 @@ const whereContainsIn = ({ const whereNotIn = ({ type = [], }: GalleryDataFilters): WhereNotInFiltersInput => { + const { options: unsupported } = UnsupportedCantoScheme; + if (type.length > 0) { + const { options: supported } = SupportedCantoScheme; + return { key: "scheme", - values: SupportedCantoScheme.options.filter( - (option) => !type.includes(option) - ), + values: [ + ...unsupported, + ...supported.filter((scheme) => !type.includes(scheme)), + ], }; } - return { key: "scheme", values: UnsupportedCantoScheme.options }; + return { key: "scheme", values: unsupported }; }; export const galleryFragment = ` diff --git a/lib/api/galleries/schema.ts b/lib/api/galleries/schema.ts index f27464b9..18754759 100644 --- a/lib/api/galleries/schema.ts +++ b/lib/api/galleries/schema.ts @@ -2,12 +2,11 @@ import z from "zod"; export const UnsupportedCantoScheme = z.enum([ "audio", - "document", "presentation", "other", ]); -export const SupportedCantoScheme = z.enum(["image", "video"]); -const CantoScheme = z.enum([ +export const SupportedCantoScheme = z.enum(["image", "video", "document"]); +export const CantoScheme = z.enum([ ...SupportedCantoScheme.options, ...UnsupportedCantoScheme.options, ]); @@ -49,12 +48,12 @@ export const MetadataAssetSchema = z.object({ TitleEN: z.string().nullable(), TitleES: z.string().nullable(), }), - height: z.string(), + height: z.coerce.number(), id: z.string(), name: z.string(), scheme: CantoScheme, url: AssetUrlSchema, - width: z.string(), + width: z.coerce.number(), }); export const DetailedAssetSchema = z @@ -62,7 +61,7 @@ export const DetailedAssetSchema = z additional: AdditionalSchema, approvalStatus: z.string(), default: AssetDefaultSchema, - height: z.string(), + height: z.coerce.number(), id: z.string(), name: z.string(), owner: z.string().nullable(), @@ -73,7 +72,7 @@ export const DetailedAssetSchema = z tag: z.array(z.string()), time: z.string(), url: AssetUrlSchema, - width: z.string(), + width: z.coerce.number(), }) .superRefine((val, ctx) => { if (val.scheme === "video" && !val.url.directUrlPreviewPlay) { diff --git a/lib/i18n/localeStrings/en/translation.json b/lib/i18n/localeStrings/en/translation.json index 1c7ab8f2..2bdb28c9 100644 --- a/lib/i18n/localeStrings/en/translation.json +++ b/lib/i18n/localeStrings/en/translation.json @@ -90,6 +90,7 @@ "gallery": { "about-the-image": "About the image", "about-the-video": "About the video", + "about-the-document": "About the document", "about-the-3d": "About the 3d Model", "about-the-gallery": "About the Gallery", "additional-information": "Additional information", @@ -99,6 +100,7 @@ "download-original": "Download original", "download-image": "Download image", "download-video": "Download video", + "download-document": "Download document", "download-3d": "Download 3d model", "download-gallery": "Download", "tags": "Tags", @@ -109,8 +111,13 @@ "back-to-galleries": "Back to galleries", "back-to-slideshows": "Back to slideshows", "image": "Image", + "image_other": "Images", "video": "Video", + "video_other": "Videos", "3d": "3D", + "3d_other": "3D Files", + "document": "Document", + "document_other": "Documents", "gallery": "Gallery", "gallery-item": "Gallery Item", "filters": { @@ -118,11 +125,8 @@ "results_one": "{{total}} result for", "results_other": "{{total}} results for", "search": "“{{value}}”", - "type": "Type: {{type}}", - "image": "Images", - "video": "Videos" + "type": "Type: {{type}}" }, - "plural-3d": "3D Files", "plural-gallery": "Galleries", "see-all": "See all", "slideshow": "Slideshow", @@ -143,6 +147,7 @@ "file-size": "File size", "credit": "Credit: {{credit}}", "date-created": "Date created", + "date-published": "Publication date", "collections": "Collections" }, "jobs": {