diff options
author | Julien Veyssier <eneiluj@posteo.net> | 2022-07-14 15:46:31 +0300 |
---|---|---|
committer | Julien Veyssier <eneiluj@posteo.net> | 2022-09-06 15:44:53 +0300 |
commit | 4d48e9d363067e6a6ce7117dbb718576a81bdedd (patch) | |
tree | 1c4fa098fc29626f2c113b9e98e93b57c3dc79e5 | |
parent | 3fec1f052dbb8cbe33172e779ac853eeb934ee62 (diff) |
rename most image stuff to file/media/attachment
Signed-off-by: Julien Veyssier <eneiluj@posteo.net>
-rw-r--r-- | appinfo/routes.php | 4 | ||||
-rw-r--r-- | lib/Controller/ImageController.php | 19 | ||||
-rw-r--r-- | lib/Service/ImageService.php | 36 | ||||
-rw-r--r-- | src/components/Editor/MediaHandler.provider.js | 14 | ||||
-rw-r--r-- | src/components/Editor/MediaHandler.vue | 95 | ||||
-rw-r--r-- | src/components/Menu/ActionImageUpload.vue | 22 | ||||
-rw-r--r-- | src/nodes/Image.js | 2 | ||||
-rw-r--r-- | src/services/SyncService.js | 12 |
8 files changed, 81 insertions, 123 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php index 99bd34973..05bf853a1 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -27,8 +27,8 @@ namespace OCA\Text\AppInfo; return [ 'routes' => [ - ['name' => 'Image#insertImageFile', 'url' => '/image/filepath', 'verb' => 'POST'], - ['name' => 'Image#uploadImage', 'url' => '/image/upload', 'verb' => 'POST'], + ['name' => 'Image#insertAttachmentFile', 'url' => '/attachment/filepath', 'verb' => 'POST'], + ['name' => 'Image#uploadAttachment', 'url' => '/attachment/upload', 'verb' => 'POST'], ['name' => 'Image#getImageFile', 'url' => '/image', 'verb' => 'GET'], ['name' => 'Image#getMediaFile', 'url' => '/media', 'verb' => 'GET'], ['name' => 'Image#getMediaFilePreview', 'url' => '/mediaPreview', 'verb' => 'GET'], diff --git a/lib/Controller/ImageController.php b/lib/Controller/ImageController.php index 36616e554..bacec4a0a 100644 --- a/lib/Controller/ImageController.php +++ b/lib/Controller/ImageController.php @@ -82,17 +82,17 @@ class ImageController extends Controller { * @param int $documentId * @param int $sessionId * @param string $sessionToken - * @param string $imagePath + * @param string $filePath * @return DataResponse */ - public function insertImageFile(int $documentId, int $sessionId, string $sessionToken, string $imagePath): DataResponse { + public function insertAttachmentFile(int $documentId, int $sessionId, string $sessionToken, string $filePath): DataResponse { if (!$this->sessionService->isValidSession($documentId, $sessionId, $sessionToken)) { return new DataResponse([], Http::STATUS_FORBIDDEN); } $userId = $this->getUserIdFromSession($documentId, $sessionId, $sessionToken); try { - $insertResult = $this->imageService->insertImageFile($documentId, $imagePath, $userId); + $insertResult = $this->imageService->insertAttachmentFile($documentId, $filePath, $userId); if (isset($insertResult['error'])) { return new DataResponse($insertResult, Http::STATUS_BAD_REQUEST); } else { @@ -114,29 +114,24 @@ class ImageController extends Controller { * @param string|null $shareToken * @return DataResponse */ - public function uploadImage(int $documentId, int $sessionId, string $sessionToken, ?string $shareToken = null): DataResponse { + public function uploadAttachment(int $documentId, int $sessionId, string $sessionToken, ?string $shareToken = null): DataResponse { if (!$this->sessionService->isValidSession($documentId, $sessionId, $sessionToken)) { return new DataResponse([], Http::STATUS_FORBIDDEN); } try { - $file = $this->getUploadedFile('image'); + $file = $this->getUploadedFile('file'); if (isset($file['tmp_name'], $file['name'], $file['type'])) { - /* - if (!in_array($file['type'], self::IMAGE_MIME_TYPES, true)) { - return new DataResponse(['error' => 'Image type not supported'], Http::STATUS_BAD_REQUEST); - } - */ $newFileResource = fopen($file['tmp_name'], 'rb'); if ($newFileResource === false) { throw new Exception('Could not read file'); } $newFileName = $file['name']; if ($shareToken) { - $uploadResult = $this->imageService->uploadImagePublic($documentId, $newFileName, $newFileResource, $shareToken); + $uploadResult = $this->imageService->uploadAttachmentPublic($documentId, $newFileName, $newFileResource, $shareToken); } else { $userId = $this->getUserIdFromSession($documentId, $sessionId, $sessionToken); - $uploadResult = $this->imageService->uploadImage($documentId, $newFileName, $newFileResource, $userId); + $uploadResult = $this->imageService->uploadAttachment($documentId, $newFileName, $newFileResource, $userId); } if (isset($uploadResult['error'])) { return new DataResponse($uploadResult, Http::STATUS_BAD_REQUEST); diff --git a/lib/Service/ImageService.php b/lib/Service/ImageService.php index f305a5e39..52f70316f 100644 --- a/lib/Service/ImageService.php +++ b/lib/Service/ImageService.php @@ -26,7 +26,6 @@ declare(strict_types=1); namespace OCA\Text\Service; -use Exception; use OCA\Text\Controller\ImageController; use OCP\Constants; use OCP\Files\Folder; @@ -39,13 +38,7 @@ use OCP\IPreview; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IShare; use OCP\Util; -use Throwable; -use GuzzleHttp\Exception\ClientException; -use GuzzleHttp\Exception\ConnectException; -use GuzzleHttp\Exception\ServerException; -use OCP\Http\Client\IClientService; use OCP\Files\IRootFolder; -use Psr\Log\LoggerInterface; use OCP\Share\IManager as ShareManager; class ImageService { @@ -59,10 +52,6 @@ class ImageService { */ private $rootFolder; /** - * @var LoggerInterface - */ - private $logger; - /** * @var IPreview */ private $previewManager; @@ -72,13 +61,11 @@ class ImageService { private $mimeTypeDetector; public function __construct(IRootFolder $rootFolder, - LoggerInterface $logger, ShareManager $shareManager, IPreview $previewManager, IMimeTypeDetector $mimeTypeDetector) { $this->rootFolder = $rootFolder; $this->shareManager = $shareManager; - $this->logger = $logger; $this->previewManager = $previewManager; $this->mimeTypeDetector = $mimeTypeDetector; } @@ -298,7 +285,7 @@ class ImageService { } /** - * Save an uploaded image in the attachment folder + * Save an uploaded file in the attachment folder * * @param int $documentId * @param string $newFileName @@ -310,7 +297,7 @@ class ImageService { * @throws \OCP\Files\InvalidPathException * @throws \OC\User\NoUserException */ - public function uploadImage(int $documentId, string $newFileName, $newFileResource, string $userId): array { + public function uploadAttachment(int $documentId, string $newFileName, $newFileResource, string $userId): array { $textFile = $this->getTextFile($documentId, $userId); if (!$textFile->isUpdateable()) { throw new NotPermittedException('No write permissions'); @@ -327,7 +314,8 @@ class ImageService { } /** - * Save an uploaded image in the attachment folder in a public context + * Save an uploaded file in the attachment folder in a public context + * * @param int|null $documentId * @param string $newFileName * @param string $newFileContent @@ -338,7 +326,7 @@ class ImageService { * @throws \OCP\Files\InvalidPathException * @throws \OC\User\NoUserException */ - public function uploadImagePublic(?int $documentId, string $newFileName, $newFileResource, string $shareToken): array { + public function uploadAttachmentPublic(?int $documentId, string $newFileName, $newFileResource, string $shareToken): array { if (!$this->hasUpdatePermissions($shareToken)) { throw new NotPermittedException('No write permissions'); } @@ -366,28 +354,28 @@ class ImageService { * @throws \OCP\Files\InvalidPathException * @throws \OC\User\NoUserException */ - public function insertImageFile(int $documentId, string $path, string $userId): array { + public function insertAttachmentFile(int $documentId, string $path, string $userId): array { $textFile = $this->getTextFile($documentId, $userId); if (!$textFile->isUpdateable()) { throw new NotPermittedException('No write permissions'); } - $imageFile = $this->getFileFromPath($path, $userId); + $originalFile = $this->getFileFromPath($path, $userId); $saveDir = $this->getAttachmentDirectoryForFile($textFile, true); - return $this->copyImageFile($imageFile, $saveDir, $textFile); + return $this->copyFile($originalFile, $saveDir, $textFile); } /** - * @param File $imageFile + * @param File $originalFile * @param Folder $saveDir * @param File $textFile * @return array * @throws NotFoundException * @throws \OCP\Files\InvalidPathException */ - private function copyImageFile(File $imageFile, Folder $saveDir, File $textFile): array { - $fileName = $this->getUniqueFileName($saveDir, $imageFile->getName()); + private function copyFile(File $originalFile, Folder $saveDir, File $textFile): array { + $fileName = $this->getUniqueFileName($saveDir, $originalFile->getName()); $targetPath = $saveDir->getPath() . '/' . $fileName; - $targetFile = $imageFile->copy($targetPath); + $targetFile = $originalFile->copy($targetPath); return [ 'name' => $fileName, 'dirname' => $saveDir->getName(), diff --git a/src/components/Editor/MediaHandler.provider.js b/src/components/Editor/MediaHandler.provider.js index 74e6ec667..def270b9a 100644 --- a/src/components/Editor/MediaHandler.provider.js +++ b/src/components/Editor/MediaHandler.provider.js @@ -1,26 +1,26 @@ export const STATE_UPLOADING = Symbol('state:uploading-state') -export const ACTION_IMAGE_PROMPT = Symbol('editor:action:image-prompt') -export const ACTION_CHOOSE_LOCAL_IMAGE = Symbol('editor:action:upload-image') +export const ACTION_ATTACHMENT_PROMPT = Symbol('editor:action:attachment-prompt') +export const ACTION_CHOOSE_LOCAL_ATTACHMENT = Symbol('editor:action:upload-attachment') export const useUploadingStateMixin = { inject: { $uploadingState: { from: STATE_UPLOADING, default: { - isUploadingImages: false, + isUploadingAttachments: false, }, }, }, } -export const useActionImagePromptMixin = { +export const useActionAttachmentPromptMixin = { inject: { - $callImagePrompt: { from: ACTION_IMAGE_PROMPT, default: () => {} }, + $callAttachmentPrompt: { from: ACTION_ATTACHMENT_PROMPT, default: () => {} }, }, } -export const useActionChooseLocalImageMixin = { +export const useActionChooseLocalAttachmentMixin = { inject: { - $callChooseLocalImage: { from: ACTION_CHOOSE_LOCAL_IMAGE, default: () => {} }, + $callChooseLocalAttachment: { from: ACTION_CHOOSE_LOCAL_ATTACHMENT, default: () => {} }, }, } diff --git a/src/components/Editor/MediaHandler.vue b/src/components/Editor/MediaHandler.vue index 1a0f939d9..32afe14f6 100644 --- a/src/components/Editor/MediaHandler.vue +++ b/src/components/Editor/MediaHandler.vue @@ -27,15 +27,15 @@ @image-paste="onPaste" @dragover.prevent.stop="setDraggedOver(true)" @dragleave.prevent.stop="setDraggedOver(false)" - @image-drop="onEditorDrop"> - <input ref="imageFileInput" - data-text-el="image-file-input" + @file-drop="onEditorDrop"> + <input ref="attachmentFileInput" + data-text-el="attachment-file-input" type="file" - accept="image/*" + accept="*/*" aria-hidden="true" class="hidden-visually" multiple - @change="onImageUploadFilePicked"> + @change="onAttachmentUploadFilePicked"> <slot /> </div> </template> @@ -43,7 +43,6 @@ <script> import { getCurrentUser } from '@nextcloud/auth' import { showError } from '@nextcloud/dialogs' -import { mimetypesImages as IMAGE_MIMES } from '../../helpers/mime.js' import { useEditorMixin, @@ -52,8 +51,8 @@ import { } from '../Editor.provider.js' import { - ACTION_IMAGE_PROMPT, - ACTION_CHOOSE_LOCAL_IMAGE, + ACTION_ATTACHMENT_PROMPT, + ACTION_CHOOSE_LOCAL_ATTACHMENT, STATE_UPLOADING, } from './MediaHandler.provider.js' @@ -64,11 +63,11 @@ export default { const val = {} Object.defineProperties(val, { - [ACTION_IMAGE_PROMPT]: { - get: () => this.showImagePrompt, + [ACTION_ATTACHMENT_PROMPT]: { + get: () => this.showAttachmentPrompt, }, - [ACTION_CHOOSE_LOCAL_IMAGE]: { - get: () => this.chooseLocalImage, + [ACTION_CHOOSE_LOCAL_ATTACHMENT]: { + get: () => this.chooseLocalFile, }, [STATE_UPLOADING]: { get: () => this.state, @@ -82,12 +81,12 @@ export default { draggedOver: false, // make it reactive to be used inject/provide state: { - isUploadingImages: false, + isUploadingAttachments: false, }, } }, computed: { - imagePath() { + initialFilePath() { return this.$file.relativePath.split('/').slice(0, -1).join('/') }, }, @@ -96,30 +95,30 @@ export default { this.draggedOver = val }, onPaste(e) { - this.uploadImageFiles(e.detail.files) + this.uploadAttachmentFiles(e.detail.files) }, onEditorDrop(e) { - this.uploadImageFiles(e.detail.files, e.detail.position) + this.uploadAttachmentFiles(e.detail.files, e.detail.position) this.draggedOver = false }, - onImageUploadFilePicked(event) { - this.uploadImageFiles(event.target.files) + onAttachmentUploadFilePicked(event) { + this.uploadAttachmentFiles(event.target.files) // Clear input to ensure that the change event will be emitted if // the same file is picked again. event.target.value = '' }, - chooseLocalImage() { - this.$refs.imageFileInput.click() + chooseLocalFile() { + this.$refs.attachmentFileInput.click() }, - async uploadImageFiles(files, position = null) { + async uploadAttachmentFiles(files, position = null) { if (!files) { return } - this.uploadingImages = true + this.state.isUploadingAttachments = true const uploadPromises = [...files].map((file) => { - return this.uploadImageFile(file, position) + return this.uploadAttachmentFile(file, position) }) return Promise.all(uploadPromises) @@ -128,13 +127,13 @@ export default { showError(err?.response?.data?.error || err.message) }) .then(() => { - this.uploadingImages = false + this.state.isUploadingAttachments = false }) }, - async uploadImageFile(file, position = null) { - this.state.isUploadingImages = true + async uploadAttachmentFile(file, position = null) { + this.state.isUploadingAttachments = true - return this.$syncService.uploadImage(file) + return this.$syncService.uploadAttachment(file) .then((response) => { this.insertAttachment( response.data?.name, response.data?.id, file.type, @@ -146,23 +145,23 @@ export default { showError(error?.response?.data?.error) }) .then(() => { - this.state.isUploadingImages = false + this.state.isUploadingAttachments = false }) }, - showImagePrompt() { + showAttachmentPrompt() { const currentUser = getCurrentUser() if (!currentUser) { return } - OC.dialogs.filepicker(t('text', 'Insert an image'), (filePath) => { - this.insertImagePath(filePath) - }, false, [], true, undefined, this.imagePath) + OC.dialogs.filepicker(t('text', 'Insert an attachment'), (filePath) => { + this.insertFromPath(filePath) + }, false, [], true, undefined, this.initialFilePath) }, - insertImagePath(imagePath) { - this.state.isUploadingImages = true + insertFromPath(filePath) { + this.state.isUploadingAttachments = true - return this.$syncService.insertImageFile(imagePath).then((response) => { + return this.$syncService.insertAttachmentFile(filePath).then((response) => { this.insertAttachment( response.data?.name, response.data?.id, response.data?.mimetype, null, response.data?.dirname @@ -171,34 +170,10 @@ export default { console.error(error) showError(error?.response?.data?.error || error.message) }).then(() => { - this.state.isUploadingImages = false + this.state.isUploadingAttachments = false }) }, insertAttachment(name, fileId, mimeType, position = null, dirname = '') { - if (IMAGE_MIMES.includes(mimeType)) { - this.insertAttachmentImage(name, fileId, mimeType, position, dirname) - return - } - this.insertAttachmentMedia(name, fileId, mimeType, position, dirname) - }, - insertAttachmentMedia(name, fileId, mimeType, position = null, dirname = '') { - // inspired by the fixedEncodeURIComponent function suggested in - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent - const src = dirname + '/' - + encodeURIComponent(name).replace(/[!'()*]/g, (c) => { - return '%' + c.charCodeAt(0).toString(16).toUpperCase() - }) - // simply get rid of brackets to make sure link text is valid - // as it does not need to be unique and matching the real file name - const alt = name.replaceAll(/[[\]]/g, '') - - const chain = position - ? this.$editor.chain().focus(position) - : this.$editor.chain() - - chain.setImage({ src, alt }).focus().run() - }, - insertAttachmentImage(name, fileId, mimeType, position = null, dirname = '') { // inspired by the fixedEncodeURIComponent function suggested in // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent const src = dirname + '/' diff --git a/src/components/Menu/ActionImageUpload.vue b/src/components/Menu/ActionImageUpload.vue index 153939f06..d0dff5234 100644 --- a/src/components/Menu/ActionImageUpload.vue +++ b/src/components/Menu/ActionImageUpload.vue @@ -33,9 +33,9 @@ aria-haspopup /> </template> <NcActionButton close-after-click - :disabled="isUploadingImages" + :disabled="isUploadingAttachments" :data-text-action-entry="`${actionEntry.key}-upload`" - @click="$callChooseLocalImage"> + @click="$callChooseLocalAttachment"> <template #icon> <Upload /> </template> @@ -43,9 +43,9 @@ </NcActionButton> <NcActionButton v-if="!$isPublic" close-after-click - :disabled="isUploadingImages" + :disabled="isUploadingAttachments" :data-text-action-entry="`${actionEntry.key}-insert`" - @click="$callImagePrompt"> + @click="$callAttachmentPrompt"> <template #icon> <Folder /> </template> @@ -62,9 +62,9 @@ import { Loading, Folder, Upload } from '../icons.js' import { useIsPublicMixin } from '../Editor.provider.js' import { BaseActionEntry } from './BaseActionEntry.js' import { - useActionImagePromptMixin, + useActionAttachmentPromptMixin, useUploadingStateMixin, - useActionChooseLocalImageMixin, + useActionChooseLocalAttachmentMixin, } from '../Editor/MediaHandler.provider.js' export default { @@ -79,18 +79,18 @@ export default { extends: BaseActionEntry, mixins: [ useIsPublicMixin, - useActionImagePromptMixin, + useActionAttachmentPromptMixin, useUploadingStateMixin, - useActionChooseLocalImageMixin, + useActionChooseLocalAttachmentMixin, ], computed: { icon() { - return this.isUploadingImages + return this.isUploadingAttachments ? Loading : this.actionEntry.icon }, - isUploadingImages() { - return this.$uploadingState.isUploadingImages + isUploadingAttachments() { + return this.$uploadingState.isUploadingAttachments }, }, } diff --git a/src/nodes/Image.js b/src/nodes/Image.js index 14410189a..3660c04e7 100644 --- a/src/nodes/Image.js +++ b/src/nodes/Image.js @@ -53,7 +53,7 @@ const Image = TiptapImage.extend({ // only catch the drop if it contains files if (event.dataTransfer.files && event.dataTransfer.files.length > 0) { const coordinates = view.posAtCoords({ left: event.clientX, top: event.clientY }) - const customEvent = new CustomEvent('image-drop', { + const customEvent = new CustomEvent('file-drop', { bubbles: true, detail: { files: event.dataTransfer.files, diff --git a/src/services/SyncService.js b/src/services/SyncService.js index fdd692f77..c8dc3d8d3 100644 --- a/src/services/SyncService.js +++ b/src/services/SyncService.js @@ -269,14 +269,14 @@ class SyncService { }) } - uploadImage(image) { + uploadAttachment(file) { const formData = new FormData() - formData.append('image', image) + formData.append('file', file) formData.append('documentId', this.document.id) formData.append('sessionId', this.session.id) formData.append('sessionToken', this.session.token) formData.append('shareToken', this.options.shareToken || '') - const url = endpointUrl('image/upload') + const url = endpointUrl('attachment/upload') return axios.post(url, formData, { headers: { 'Content-Type': 'multipart/form-data', @@ -284,14 +284,14 @@ class SyncService { }) } - insertImageFile(imagePath) { + insertAttachmentFile(filePath) { const params = { documentId: this.document.id, sessionId: this.session.id, sessionToken: this.session.token, - imagePath, + filePath, } - const url = endpointUrl('image/filepath') + const url = endpointUrl('attachment/filepath') return axios.post(url, params) } |