Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new private upload-media package #66290

Open
wants to merge 46 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8a57140
Add new private `upload-media` package
swissspidy Oct 21, 2024
808700e
Add missing readme
swissspidy Oct 22, 2024
7a9a762
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Oct 22, 2024
6022cf0
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Oct 23, 2024
3f30935
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Oct 24, 2024
91f7687
Make `updateSettings` private
swissspidy Oct 24, 2024
b1b0cb5
Remove empty line
swissspidy Oct 24, 2024
5d00adb
Add back some of the missing utils
swissspidy Oct 24, 2024
72d474f
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Oct 24, 2024
07680ca
Update docs now
swissspidy Oct 24, 2024
38c3df6
Remove meetings (#66421)
ndiego Oct 24, 2024
06e345e
Site editor: remove "default" admin CSS (#66431)
ellatrix Oct 24, 2024
8f99999
Fix: JSON Schema Docgen doesn't work on Windows OS (#66414)
t-hamano Oct 25, 2024
a198bd2
Revise zoom layout shift fix (#66390)
stokesman Oct 25, 2024
4d4142c
Zoom out: Add keyboard shortcut in editor (#66400)
ntsekouras Oct 25, 2024
7f2549c
Compose: Fix React Complier error for 'useCopyToClipboard' (#66444)
Mamaduka Oct 25, 2024
f0b988c
Style Book: Fix React Compiler error (#66445)
Mamaduka Oct 25, 2024
0b066a9
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Oct 25, 2024
3cfa25a
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Oct 25, 2024
a1f044f
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Nov 4, 2024
57135d8
Add `ts-ignore`
swissspidy Nov 4, 2024
a76fcc7
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Nov 25, 2024
5b3c022
Block editor: Add `MediaUploadProvider` (#66380)
swissspidy Nov 25, 2024
1dc086d
Change order in `package.json`
swissspidy Nov 25, 2024
845cf78
Rip out most code
swissspidy Nov 25, 2024
8cd6177
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Nov 30, 2024
a1f0282
A bunch of fixes
swissspidy Dec 2, 2024
bae3e67
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Dec 2, 2024
93e9ec9
Fixes
swissspidy Dec 2, 2024
6176a66
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Dec 2, 2024
17dc47e
Move to folder for RN compat
swissspidy Dec 2, 2024
8b6f249
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Dec 2, 2024
4f5a0d0
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Dec 10, 2024
c772bd5
Remove default value
swissspidy Dec 10, 2024
addc7ff
Pass to `privateSettings` instead
swissspidy Dec 10, 2024
d2e8255
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Dec 10, 2024
d423b45
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Dec 11, 2024
d3ec207
Move validation to block-editor/upload-media
swissspidy Dec 11, 2024
9e73bd5
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Dec 11, 2024
ad01ff2
Use non-empty files in test
swissspidy Dec 11, 2024
e498986
fix api reference
swissspidy Dec 11, 2024
b77e527
Update readme a little bit
swissspidy Dec 12, 2024
00f7466
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Dec 12, 2024
4c1c576
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Dec 13, 2024
ba97bbf
Undo change to privateSettings
swissspidy Dec 13, 2024
e8b3755
Merge branch 'trunk' into add/61447-upload-media-pkg
swissspidy Dec 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/check-licenses.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { spawnSync } from 'node:child_process';
*/
import { checkDepsInTree } from '../packages/scripts/utils/license.js';

const ignored = [ '@ampproject/remapping' ];
const ignored = [ '@ampproject/remapping', 'webpack' ];

/*
* `wp-scripts check-licenses` uses prod and dev dependencies of the package to scan for dependencies. With npm workspaces, workspace packages (the @wordpress/* packages) are not listed in the main package json and this approach does not work.
Expand Down
60 changes: 60 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

85 changes: 81 additions & 4 deletions packages/block-editor/src/components/provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
* WordPress dependencies
*/
import { useDispatch } from '@wordpress/data';
import { useEffect } from '@wordpress/element';
import { useEffect, useMemo } from '@wordpress/element';
import { SlotFillProvider } from '@wordpress/components';
//eslint-disable-next-line import/no-extraneous-dependencies -- Experimental package, not published.
import {
MediaUploadProvider,
store as uploadStore,
} from '@wordpress/upload-media';

/**
* Internal dependencies
Expand All @@ -14,12 +19,71 @@ import { store as blockEditorStore } from '../../store';
import { BlockRefsProvider } from './block-refs-provider';
import { unlock } from '../../lock-unlock';
import KeyboardShortcuts from '../keyboard-shortcuts';
import useMediaUploadSettings from './use-media-upload-settings';

/** @typedef {import('@wordpress/data').WPDataRegistry} WPDataRegistry */

const noop = () => {};

/**
* Upload a media file when the file upload button is activated
* or when adding a file to the editor via drag & drop.
*
* @param {WPDataRegistry} registry
* @param {Object} $3 Parameters object passed to the function.
* @param {Array} $3.allowedTypes Array with the types of media that can be uploaded, if unset all types are allowed.
* @param {Object} $3.additionalData Additional data to include in the request.
* @param {Array<File>} $3.filesList List of files.
* @param {Function} $3.onError Function called when an error happens.
* @param {Function} $3.onFileChange Function called each time a file or a temporary representation of the file is available.
* @param {Function} $3.onSuccess Function called once a file has completely finished uploading, including thumbnails.
* @param {Function} $3.onBatchSuccess Function called once all files in a group have completely finished uploading, including thumbnails.
*/
function mediaUpload(
registry,
{
allowedTypes,
additionalData = {},
filesList,
onError = noop,
onFileChange,
onSuccess,
onBatchSuccess,
}
) {
void registry.dispatch( uploadStore ).addItems( {
files: filesList,
onChange: onFileChange,
onSuccess,
onBatchSuccess,
onError: ( { message } ) => onError( message ),
additionalData,
allowedTypes,
} );
}

export const ExperimentalBlockEditorProvider = withRegistryProvider(
( props ) => {
const { children, settings, stripExperimentalSettings = false } = props;
const {
settings: _settings,
registry,
stripExperimentalSettings = false,
} = props;

const mediaUploadSettings = useMediaUploadSettings( _settings );

let settings = _settings;

if ( window.__experimentalMediaProcessing && _settings.mediaUpload ) {
// Create a new variable so that the original props.settings.mediaUpload is not modified.
settings = useMemo(
() => ( {
..._settings,
mediaUpload: mediaUpload.bind( null, registry ),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's a bit confusing for me here, is that if you use the selector to retrieve the settings, you'll get a different "mediaUpload" than the one you passed as a setting.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but it's the only way to ensure backward compatibility.

You pass mediaUpload to block-editor settings as the function to upload media to a server.

Other users of block-editor (such as block-library) also use this function to upload media.

The (worse) alternative would be to tell everyone to use addItems() action instead and stop using getSettings().mediaUpload

} ),
[ _settings, registry ]
);
}

const { __experimentalUpdateSettings } = unlock(
useDispatch( blockEditorStore )
Expand All @@ -44,12 +108,25 @@ export const ExperimentalBlockEditorProvider = withRegistryProvider(
// Syncs the entity provider with changes in the block-editor store.
useBlockSync( props );

return (
const children = (
<SlotFillProvider passthrough>
{ ! settings?.isPreviewMode && <KeyboardShortcuts.Register /> }
<BlockRefsProvider>{ children }</BlockRefsProvider>
<BlockRefsProvider>{ props.children }</BlockRefsProvider>
</SlotFillProvider>
);

if ( window.__experimentalMediaProcessing ) {
return (
<MediaUploadProvider
settings={ mediaUploadSettings }
useSubRegistry={ false }
>
{ children }
</MediaUploadProvider>
);
}

return children;
}
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* WordPress dependencies
*/
import { useMemo } from '@wordpress/element';

/**
* React hook used to compute the media upload settings to use in the post editor.
*
* @param {Object} settings Media upload settings prop.
*
* @return {Object} Media upload settings.
*/
function useMediaUploadSettings( settings ) {
return useMemo(
() => ( {
mediaUpload: settings.mediaUpload,
mediaSideload: settings.mediaSideload,
maxUploadFileSize: settings.maxUploadFileSize,
allowedMimeTypes: settings.allowedMimeTypes,
} ),
[ settings ]
);
}

export default useMediaUploadSettings;
3 changes: 3 additions & 0 deletions packages/block-editor/src/store/private-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ const castArray = ( maybeArray ) =>
const privateSettings = [
'inserterMediaCategories',
'blockInspectorAnimation',
'mediaSideload',
'validateFileSize',
'validateMimeType',
];

/**
Expand Down
1 change: 1 addition & 0 deletions packages/editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ _Parameters_
- _$0.maxUploadFileSize_ `?number`: Maximum upload size in bytes allowed for the site.
- _$0.onError_ `Function`: Function called when an error happens.
- _$0.onFileChange_ `Function`: Function called each time a file or a temporary representation of the file is available.
- _$0.onSuccess_ `Function`: Function called after the final representation of the file is available.

### MediaUploadCheck

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
*/
import inserterMediaCategories from '../media-categories';
import { mediaUpload } from '../../utils';
import { default as mediaSideload } from '../../utils/media-sideload';
import { store as editorStore } from '../../store';
import { unlock } from '../../lock-unlock';
import { useGlobalStylesContext } from '../global-styles-provider';
Expand All @@ -45,6 +46,7 @@ const BLOCK_EDITOR_SETTINGS = [
'__experimentalGlobalStylesBaseStyles',
'alignWide',
'blockInspectorTabs',
'maxUploadFileSize',
'allowedMimeTypes',
'bodyPlaceholder',
'canLockBlocks',
Expand Down Expand Up @@ -290,6 +292,7 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
isDistractionFree,
keepCaretInsideBlock,
mediaUpload: hasUploadPermissions ? mediaUpload : undefined,
mediaSideload: hasUploadPermissions ? mediaSideload : undefined,
__experimentalBlockPatterns: blockPatterns,
[ selectBlockPatternsKey ]: ( select ) => {
const { hasFinishedResolution, getBlockPatternsForPostType } =
Expand Down
13 changes: 13 additions & 0 deletions packages/editor/src/utils/media-sideload/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* WordPress dependencies
*/
import { privateApis } from '@wordpress/media-utils';

/**
* Internal dependencies
*/
import { unlock } from '../../lock-unlock';

const { sideloadMedia: mediaSideload } = unlock( privateApis );

export default mediaSideload;
1 change: 1 addition & 0 deletions packages/editor/src/utils/media-sideload/index.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default function mediaSideload() {}
5 changes: 4 additions & 1 deletion packages/editor/src/utils/media-upload/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const noop = () => {};
* @param {?number} $0.maxUploadFileSize Maximum upload size in bytes allowed for the site.
* @param {Function} $0.onError Function called when an error happens.
* @param {Function} $0.onFileChange Function called each time a file or a temporary representation of the file is available.
* @param {Function} $0.onSuccess Function called after the final representation of the file is available.
*/
export default function mediaUpload( {
additionalData = {},
Expand All @@ -35,6 +36,7 @@ export default function mediaUpload( {
maxUploadFileSize,
onError = noop,
onFileChange,
onSuccess,
} ) {
const { getCurrentPost, getEditorSettings } = select( editorStore );
const {
Expand Down Expand Up @@ -77,8 +79,9 @@ export default function mediaUpload( {
} else {
clearSaveLock();
}
onFileChange( file );
onFileChange?.( file );
},
onSuccess,
additionalData: {
...postData,
...additionalData,
Expand Down
1 change: 0 additions & 1 deletion packages/media-utils/src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ export type Attachment = BetterOmit<
};

export type OnChangeHandler = ( attachments: Partial< Attachment >[] ) => void;
export type OnSuccessHandler = ( attachments: Partial< Attachment >[] ) => void;
export type OnErrorHandler = ( error: Error ) => void;

export type CreateRestAttachment = Partial< RestAttachment >;
Expand Down
27 changes: 18 additions & 9 deletions packages/media-utils/src/utils/upload-media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@ import type {
Attachment,
OnChangeHandler,
OnErrorHandler,
OnSuccessHandler,
} from './types';
import { uploadToServer } from './upload-to-server';
import { validateMimeType } from './validate-mime-type';
import { validateMimeTypeForUser } from './validate-mime-type-for-user';
import { validateFileSize } from './validate-file-size';
import { UploadError } from './upload-error';

declare global {
interface Window {
__experimentalMediaProcessing?: boolean;
}
}

interface UploadMediaArgs {
// Additional data to include in the request.
additionalData?: AdditionalData;
Expand All @@ -33,8 +38,6 @@ interface UploadMediaArgs {
onError?: OnErrorHandler;
// Function called each time a file or a temporary representation of the file is available.
onFileChange?: OnChangeHandler;
// Function called once a file has completely finished uploading, including thumbnails.
onSuccess?: OnSuccessHandler;
// List of allowed mime types and file extensions.
wpAllowedMimeTypes?: Record< string, string > | null;
// Abort signal.
Expand Down Expand Up @@ -69,8 +72,11 @@ export function uploadMedia( {

const filesSet: Array< Partial< Attachment > | null > = [];
const setAndUpdateFiles = ( index: number, value: Attachment | null ) => {
if ( filesSet[ index ]?.url ) {
revokeBlobURL( filesSet[ index ].url );
// For client-side media processing, this is handled by the upload-media package.
if ( ! window.__experimentalMediaProcessing ) {
if ( filesSet[ index ]?.url ) {
revokeBlobURL( filesSet[ index ].url );
}
}
filesSet[ index ] = value;
onFileChange?.(
Expand Down Expand Up @@ -107,10 +113,13 @@ export function uploadMedia( {

validFiles.push( mediaFile );

// Set temporary URL to create placeholder media file, this is replaced
// with final file from media gallery when upload is `done` below.
filesSet.push( { url: createBlobURL( mediaFile ) } );
onFileChange?.( filesSet as Array< Partial< Attachment > > );
// For client-side media processing, this is handled by the upload-media package.
if ( ! window.__experimentalMediaProcessing ) {
// Set temporary URL to create placeholder media file, this is replaced
// with final file from media gallery when upload is `done` below.
filesSet.push( { url: createBlobURL( mediaFile ) } );
onFileChange?.( filesSet as Array< Partial< Attachment > > );
}
}

validFiles.map( async ( file, index ) => {
Expand Down
Loading
Loading