UNPKG

@wordpress/editor

Version:
230 lines (219 loc) 6.73 kB
/** * The `editor` settings here need to be in sync with the corresponding ones in `editor` package. * See `packages/editor/src/components/media-categories/index.js`. * * In the future we could consider creating an Openvese package that can be used in both `editor` and `site-editor`. * The rest of the settings would still need to be in sync though. */ /** * WordPress dependencies */ import { __, sprintf, _x } from '@wordpress/i18n'; import { resolveSelect } from '@wordpress/data'; import { decodeEntities } from '@wordpress/html-entities'; /** * Internal dependencies */ import { store as coreStore } from '@wordpress/core-data'; /** @typedef {import('@wordpress/block-editor').InserterMediaRequest} InserterMediaRequest */ /** @typedef {import('@wordpress/block-editor').InserterMediaItem} InserterMediaItem */ /** @typedef {import('@wordpress/block-editor').InserterMediaCategory} InserterMediaCategory */ const getExternalLink = ( url, text ) => `<a ${ getExternalLinkAttributes( url ) }>${ text }</a>`; const getExternalLinkAttributes = ( url ) => `href="${ url }" target="_blank" rel="noreferrer noopener"`; const getOpenverseLicense = ( license, licenseVersion ) => { let licenseName = license.trim(); // PDM has no abbreviation if ( license !== 'pdm' ) { licenseName = license.toUpperCase().replace( 'SAMPLING', 'Sampling' ); } // If version is known, append version to the name. // The license has to have a version to be valid. Only // PDM (public domain mark) doesn't have a version. if ( licenseVersion ) { licenseName += ` ${ licenseVersion }`; } // For licenses other than public-domain marks, prepend 'CC' to the name. if ( ! [ 'pdm', 'cc0' ].includes( license ) ) { licenseName = `CC ${ licenseName }`; } return licenseName; }; const getOpenverseCaption = ( item ) => { const { title, foreign_landing_url: foreignLandingUrl, creator, creator_url: creatorUrl, license, license_version: licenseVersion, license_url: licenseUrl, } = item; const fullLicense = getOpenverseLicense( license, licenseVersion ); const _creator = decodeEntities( creator ); let _caption; if ( _creator ) { _caption = title ? sprintf( // translators: %1s: Title of a media work from Openverse; %2$s: Name of the work's creator; %3s: Work's licence e.g: "CC0 1.0". _x( '"%1$s" by %2$s/ %3$s', 'caption' ), getExternalLink( foreignLandingUrl, decodeEntities( title ) ), creatorUrl ? getExternalLink( creatorUrl, _creator ) : _creator, licenseUrl ? getExternalLink( `${ licenseUrl }?ref=openverse`, fullLicense ) : fullLicense ) : sprintf( // translators: %1s: Link attributes for a given Openverse media work; %2s: Name of the work's creator; %3s: Works's licence e.g: "CC0 1.0". _x( '<a %1$s>Work</a> by %2$s/ %3$s', 'caption' ), getExternalLinkAttributes( foreignLandingUrl ), creatorUrl ? getExternalLink( creatorUrl, _creator ) : _creator, licenseUrl ? getExternalLink( `${ licenseUrl }?ref=openverse`, fullLicense ) : fullLicense ); } else { _caption = title ? sprintf( // translators: %1s: Title of a media work from Openverse; %2s: Work's licence e.g: "CC0 1.0". _x( '"%1$s"/ %2$s', 'caption' ), getExternalLink( foreignLandingUrl, decodeEntities( title ) ), licenseUrl ? getExternalLink( `${ licenseUrl }?ref=openverse`, fullLicense ) : fullLicense ) : sprintf( // translators: %1s: Link attributes for a given Openverse media work; %2s: Works's licence e.g: "CC0 1.0". _x( '<a %1$s>Work</a>/ %2$s', 'caption' ), getExternalLinkAttributes( foreignLandingUrl ), licenseUrl ? getExternalLink( `${ licenseUrl }?ref=openverse`, fullLicense ) : fullLicense ); } return _caption.replace( /\s{2}/g, ' ' ); }; const coreMediaFetch = async ( query = {} ) => { const mediaItems = await resolveSelect( coreStore ).getEntityRecords( 'postType', 'attachment', { ...query, orderBy: !! query?.search ? 'relevance' : 'date', } ); return mediaItems.map( ( mediaItem ) => ( { ...mediaItem, alt: mediaItem.alt_text, url: mediaItem.source_url, previewUrl: mediaItem.media_details?.sizes?.medium?.source_url, caption: mediaItem.caption?.raw, } ) ); }; /** @type {InserterMediaCategory[]} */ const inserterMediaCategories = [ { name: 'images', labels: { name: __( 'Images' ), search_items: __( 'Search images' ), }, mediaType: 'image', async fetch( query = {} ) { return coreMediaFetch( { ...query, media_type: 'image' } ); }, }, { name: 'videos', labels: { name: __( 'Videos' ), search_items: __( 'Search videos' ), }, mediaType: 'video', async fetch( query = {} ) { return coreMediaFetch( { ...query, media_type: 'video' } ); }, }, { name: 'audio', labels: { name: __( 'Audio' ), search_items: __( 'Search audio' ), }, mediaType: 'audio', async fetch( query = {} ) { return coreMediaFetch( { ...query, media_type: 'audio' } ); }, }, { name: 'openverse', labels: { name: __( 'Openverse' ), search_items: __( 'Search Openverse' ), }, mediaType: 'image', async fetch( query = {} ) { const defaultArgs = { mature: false, excluded_source: 'flickr,inaturalist,wikimedia', license: 'pdm,cc0', }; const finalQuery = { ...query, ...defaultArgs }; const mapFromInserterMediaRequest = { per_page: 'page_size', search: 'q', }; const url = new URL( 'https://api.openverse.org/v1/images/' ); Object.entries( finalQuery ).forEach( ( [ key, value ] ) => { const queryKey = mapFromInserterMediaRequest[ key ] || key; url.searchParams.set( queryKey, value ); } ); const response = await window.fetch( url, { headers: { 'User-Agent': 'WordPress/inserter-media-fetch', }, } ); const jsonResponse = await response.json(); const results = jsonResponse.results; return results.map( ( result ) => ( { ...result, // This is a temp solution for better titles, until Openverse API // completes the cleaning up of some titles of their upstream data. title: result.title?.toLowerCase().startsWith( 'file:' ) ? result.title.slice( 5 ) : result.title, sourceId: result.id, id: undefined, caption: getOpenverseCaption( result ), previewUrl: result.thumbnail, } ) ); }, getReportUrl: ( { sourceId } ) => `https://wordpress.org/openverse/image/${ sourceId }/report/`, isExternalResource: true, }, ]; export default inserterMediaCategories;