From a27ca8668a9b96651785bc4ce67478fc933551db Mon Sep 17 00:00:00 2001 From: Elorfin Date: Wed, 9 Feb 2022 06:56:42 +0100 Subject: [PATCH] [File] adds basic info when file has no player --- .../Resource/Types/FileSerializer.php | 18 ++++- .../resources/file/player/components/main.jsx | 13 ++++ .../file/player/components/overview.jsx | 68 +++++++++++++++++++ .../resources/file/player/containers/main.jsx | 1 + 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 src/main/core/Resources/modules/resources/file/player/components/overview.jsx diff --git a/src/main/core/API/Serializer/Resource/Types/FileSerializer.php b/src/main/core/API/Serializer/Resource/Types/FileSerializer.php index fafc563f8c2..4f24d5b7847 100644 --- a/src/main/core/API/Serializer/Resource/Types/FileSerializer.php +++ b/src/main/core/API/Serializer/Resource/Types/FileSerializer.php @@ -8,7 +8,9 @@ use Claroline\CoreBundle\Entity\Resource\ResourceNode; use Claroline\CoreBundle\Event\GenericDataEvent; use Claroline\CoreBundle\Event\Resource\File\LoadFileEvent; +use Claroline\CoreBundle\Library\Normalizer\TextNormalizer; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Mime\MimeTypes; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\RouterInterface; @@ -48,11 +50,23 @@ public function getName() */ public function serialize(File $file): array { - $options = [ + $ext = pathinfo($file->getHashName(), PATHINFO_EXTENSION); + if (empty($ext)) { + $mimeTypeGuesser = new MimeTypes(); + $guessedExtension = $mimeTypeGuesser->getExtensions($file->getMimeType()); + if (!empty($guessedExtension)) { + $ext = $guessedExtension[0]; + } + } + + $fileName = TextNormalizer::toKey(str_replace('.'.$ext, '', $file->getResourceNode()->getName())).'.'.$ext; + + $serialized = [ 'id' => $file->getUuid(), 'size' => $file->getSize(), 'opening' => $file->getOpening(), 'commentsActivated' => $file->getResourceNode()->isCommentsActivated(), + 'name' => $fileName, // the name of the file which will be used for file download 'hashName' => $file->getHashName(), // We generate URL here because the stream API endpoint uses ResourceNode ID, @@ -75,7 +89,7 @@ public function serialize(File $file): array $additionalFileData = $fallBackEvent->getData(); } - return array_merge($additionalFileData, $options); + return array_merge($additionalFileData, $serialized); } public function deserialize($data, File $file, array $options = []): File diff --git a/src/main/core/Resources/modules/resources/file/player/components/main.jsx b/src/main/core/Resources/modules/resources/file/player/components/main.jsx index b1c8dfa868d..a41d4b25bbb 100644 --- a/src/main/core/Resources/modules/resources/file/player/components/main.jsx +++ b/src/main/core/Resources/modules/resources/file/player/components/main.jsx @@ -12,6 +12,7 @@ import {File as FileTypes} from '#/main/core/files/prop-types' import {constants} from '#/main/core/resources/file/constants' import {ContentComments} from '#/main/app/content/components/comments' +import {PlayerOverview} from '#/main/core/resources/file/player/components/overview' // TODO : display a standard player with file info if no custom one const PlayerMain = (props) => { @@ -55,6 +56,17 @@ const PlayerMain = (props) => { } props.download(props.resourceNode) + + console.log(props.mimeType) + + return ( + + ) }} /> ) @@ -70,6 +82,7 @@ PlayerMain.propTypes = { file: T.shape( FileTypes.propTypes ).isRequired, + workspace: T.object, createComment: T.func.isRequired, editComment: T.func.isRequired, deleteComment: T.func.isRequired diff --git a/src/main/core/Resources/modules/resources/file/player/components/overview.jsx b/src/main/core/Resources/modules/resources/file/player/components/overview.jsx new file mode 100644 index 00000000000..ae627146c31 --- /dev/null +++ b/src/main/core/Resources/modules/resources/file/player/components/overview.jsx @@ -0,0 +1,68 @@ +import React, {Fragment} from 'react' +import {PropTypes as T} from 'prop-types' +import get from 'lodash/get' + +import {trans, fileSize} from '#/main/app/intl' +import {CALLBACK_BUTTON, URL_BUTTON} from '#/main/app/buttons' +import {Toolbar} from '#/main/app/action' +import {ContentHtml} from '#/main/app/content/components/html' +import {route} from '#/main/core/workspace/routing' + +const PlayerOverview = (props) => + + {get(props.resourceNode, 'meta.description') && +
+ {get(props.resourceNode, 'meta.description')} +
+ } + +
+ + {props.file.name} + + {fileSize(props.file.size)+trans('bytes_short')} + +
+ + props.download(props.resourceNode), + primary: true + }, { + name: 'home', + type: URL_BUTTON, // we require an URL_BUTTON here to escape the embedded resource router + icon: 'fa fa-fw fa-home', + label: trans('return-home', {}, 'actions'), + target: '#'+route(props.workspace), + displayed: !!props.workspace + } + ]} + /> +
+ +PlayerOverview.propTypes = { + file: T.shape({ + name: T.string.isRequired, + size: T.number + }).isRequired, + resourceNode: T.shape({ + name: T.string.isRequired, + meta: T.shape({ + description: T.string + }) + }), + workspace: T.object, + download: T.func.isRequired +} + +export { + PlayerOverview +} diff --git a/src/main/core/Resources/modules/resources/file/player/containers/main.jsx b/src/main/core/Resources/modules/resources/file/player/containers/main.jsx index 126d3d5bcb3..c920bccaf26 100644 --- a/src/main/core/Resources/modules/resources/file/player/containers/main.jsx +++ b/src/main/core/Resources/modules/resources/file/player/containers/main.jsx @@ -19,6 +19,7 @@ const PlayerMain = connect( mimeType: selectors.mimeType(state), file: selectors.file(state), resourceNode: resourceSelectors.resourceNode(state), + workspace: resourceSelectors.workspace(state), canEdit: hasPermission('edit', resourceSelectors.resourceNode(state)) }), (dispatch) => ({