From 697bff2bf7ea7e8a7d57cc1e3dfabf0b0729d248 Mon Sep 17 00:00:00 2001 From: JoaoSRaposo Date: Wed, 23 Oct 2024 10:15:33 +0100 Subject: [PATCH] Bug fix/#904 file actions reload fix unview fix two actions for visual (#78) * Chaging t('files to t('files_external_ethswarm Fixing unview file and folder message Adding hejbit overlay and swarmref action to all files and folders to "support" NC fileactions navigation bug * Option with two separate file actions (Overlay and CopySwarm Ref) * Improving reload logic * Fixing Exec Batch Error - Now it's possible to select the action from the top file menu * FIX - Improved Fileaction reload fix * Fixing Unview file on NC29 & NC30 Organizing TODOs in Fileaction * fix(904): previousPathHasSwarm to check with the first file available on index 0 instead --------- Co-authored-by: Mahyar Iranibazaz --- img/hejbit-logo.svg | 1 + lib/Sabre/PropfindPlugin.php | 29 +++--- src/fileactions.js | 169 +++++++++++++++++++++++++---------- 3 files changed, 138 insertions(+), 61 deletions(-) create mode 100644 img/hejbit-logo.svg diff --git a/img/hejbit-logo.svg b/img/hejbit-logo.svg new file mode 100644 index 0000000..874ab17 --- /dev/null +++ b/img/hejbit-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/Sabre/PropfindPlugin.php b/lib/Sabre/PropfindPlugin.php index 6138895..f932367 100755 --- a/lib/Sabre/PropfindPlugin.php +++ b/lib/Sabre/PropfindPlugin.php @@ -65,13 +65,14 @@ public function propFind(PropFind $propFind, INode $node) { { return $class->getSwarmRef($filename, $storageid); }); - $propFind->handle("{http://nextcloud.org/ns}hidden", function () use ($class, $storageid, $filename) - { - if($class->getVisiblity($filename, $storageid)==1){ - return "false"; - } ; - return "true"; - }); + + if($class->getVisiblity($filename, $storageid)==1){ + $propFind->set("{http://nextcloud.org/ns}hidden","false",200); + } + else{ + $propFind->set("{http://nextcloud.org/ns}hidden","true",200); + } + $propFind->handle(self::ETHSWARM_NODE, function () use ($class, $storageid, $filename) { return "true"; @@ -88,13 +89,13 @@ public function propFind(PropFind $propFind, INode $node) { } $class = $this->EthswarmService; - $propFind->handle("{http://nextcloud.org/ns}hidden", function () use ($class, $storageid, $filename) - { - if($class->getVisiblity($filename, $storageid)==1){ - return "false"; - } ; - return "true"; - }); + if($class->getVisiblity($filename, $storageid)==1){ + $propFind->set("{http://nextcloud.org/ns}hidden","false",200); + } + else{ + $propFind->set("{http://nextcloud.org/ns}hidden","true",200); + } + $propFind->handle(self::ETHSWARM_NODE, function () use ($class, $storageid, $filename) { return "true"; diff --git a/src/fileactions.js b/src/fileactions.js index 8869ca2..a41615d 100644 --- a/src/fileactions.js +++ b/src/fileactions.js @@ -1,4 +1,3 @@ - /* * @copyright Copyright (c) 2022 Henry Bergström * @@ -21,10 +20,24 @@ * */ + +/* TODO - Unview action : Support Batch Option on - Problem > Can't import p-queue: Import p-queue +Import p-queue +Batch option import PQueue from 'p-queue'; +Batch option const queue = new PQueue({ concurrency: 5 }); +*/ + +// TODO - Unview action : Change alert o OC.dialogs.confirm + +// TODO - Unview action : Change emit('files:node:deleted', node) to other like files:list:updated + +// TODO - All actions Change the enable function so all this actions don't appear on FilesListTableHeaderActions + import { emit,subscribe } from '@nextcloud/event-bus'; import { FileAction, registerDavProperty, registerFileAction, FileType } from "@nextcloud/files"; import HideSource from "@material-design-icons/svg/filled/hide_source.svg"; import SwarmSvg from "../img/swarm-logo.svg"; +import HejBitSvg from "../img/hejbit-logo.svg"; import axios from '@nextcloud/axios'; import Close from "@material-design-icons/svg/filled/close.svg"; import CloudOff from "@material-design-icons/svg/filled/cloud_off.svg"; @@ -61,21 +74,22 @@ const isAllFolders = (nodes) => { registerDavProperty("nc:ethswarm-fileref"); registerDavProperty("nc:ethswarm-node"); -const actionDataEthswarmCopyRefAndOverlay = { - id: 'EthswarmCopyRefAndOverlay', +const actionDataEthswarmOverlay = { + id: 'EthswarmOverlay', + displayName() { return ''; }, - altText() { - return t('files_external_ethswarm', "Copy Swarm reference to clipboard"); - }, enabled(files, view) { if (files.length !== 1) // We don't support batch actions return false; - const attrs = files[0].attributes["ethswarm-fileref"]; + + // To fix fileaction navigation bug this action is now available for + // files and folders on Swarm storage + const attrs = files[0].attributes["ethswarm-node"]; if (attrs === undefined) return false; @@ -85,15 +99,15 @@ const actionDataEthswarmCopyRefAndOverlay = { return true; }, + iconSvgInline(files, view) { + return Buffer.from(HejBitSvg.split(",")[1], 'base64'); + }, + + inline(file, view) { - // Determine whether to render the inline element - // For example, only for PDF files return true; }, - iconSvgInline(files, view) { - return Buffer.from(SwarmSvg.split(",")[1], 'base64'); - }, async renderInline(file, view) { // Create the overlay element @@ -117,32 +131,91 @@ const actionDataEthswarmCopyRefAndOverlay = { return overlay; }, + async exec(node, view) { + if (node.type === FileType.Folder) { + OC.dialogs.info(t('files_external_ethswarm', 'Folder structure is not yet supported on Swarm. This folder is only available on Nextcloud, although all files within it are accessible on Swarm.'), t('files_external_ethswarm', 'Hejbit')); + }else if (node.type === FileType.File) { + OC.dialogs.info(t('files_external_ethswarm', 'This file is on Swarm Network by Hejbit!'), t('files_external_ethswarm', 'Hejbit')); + } + + }, + + execBatch(nodes, view) { + return Promise.all(nodes.map(node => this.exec(node, view))); + } +}; + + + +const EthswarmOverlay = new FileAction(actionDataEthswarmOverlay); + +registerFileAction(EthswarmOverlay); + + +const actionDataEthswarmCopyRef = { + id: 'EthswarmCopyRef', + + displayName() { + return t('files_external_ethswarm', "Copy Swarm reference to clipboard"); + }, + + altText() { + return t('files_external_ethswarm', "Copy Swarm reference to clipboard"); + }, + + enabled(files, view) { + if (files.length !== 1) // We don't support batch actions + return false; + + // To fix fileaction navigation bug this action is now available for + // files and folders on Swarm storage + const attrs = files[0].attributes["ethswarm-node"]; + + if (attrs === undefined) + return false; + else if (attrs === "") + return false; + + return true; + }, + + inline(file, view) { + // Determine whether to render the inline element + // For example, only for PDF files + return false; + }, + + iconSvgInline(files, view) { + return Buffer.from(SwarmSvg.split(",")[1], 'base64'); + }, + + async exec(node, view) { const swarmref = node.attributes["ethswarm-fileref"]; + if (node.type === FileType.Folder) { + OC.dialogs.info(t('files_external_ethswarm', 'Folder structure is not yet supported on Swarm. This folder is only available on Nextcloud, although all files within it are accessible on Swarm.'), t('files_external_ethswarm', 'Swarm reference')); + return; + } navigator.clipboard.writeText(swarmref) .then(() => { - /* clipboard successfully set */ + // clipboard successfully set OC.dialogs.info(t('files_external_ethswarm', 'The following Swarm reference has been copied to the clipboard: ') + swarmref, t('files_external_ethswarm', 'Swarm reference')); }, () => { - /* clipboard write failed */ + // clipboard write failed OC.dialogs.info(t('files_external_ethswarm', 'Unable to write to the clipboard, you can manually copy the Swarm reference below: ') + swarmref, t('files_external_ethswarm', 'Swarm reference')); }); }, - execBatch() { - // Not currently supported. + execBatch(nodes,view) { + return Promise.all(nodes.map(node => this.exec(node, view))); } }; -const EthswarmCopyRefAndOverlay = new FileAction(actionDataEthswarmCopyRefAndOverlay); +const EthswarmCopyRef = new FileAction(actionDataEthswarmCopyRef); + +registerFileAction(EthswarmCopyRef); -registerFileAction(EthswarmCopyRefAndOverlay); -// TODO: Support Batch Option - Challenge: Import p-queue -// TODO: Support Hide Folder Option - Challenge 1 : Change the enabled function to check if the node is a folder on swarm table -// TODO: Support Hide Folder Option - Step 2 : Change altert message to hide folder -// TODO: Batch option import PQueue from 'p-queue'; -// TODO: Batch option const queue = new PQueue({ concurrency: 5 }); const actionDataUnviewFile ={ id: 'unviewFile', displayName(nodes, view) { @@ -150,7 +223,7 @@ const actionDataUnviewFile ={ * If we're in the sharing view, we can only unshare */ if (isMixedUnshareAndDelete(nodes)) { - return t('files', 'Unview and unshare'); + return t('files_external_ethswarm', 'Unview and unshare'); } /** * If those nodes are all the root node of a @@ -158,9 +231,9 @@ const actionDataUnviewFile ={ */ if (canUnshareOnly(nodes)) { if (nodes.length === 1) { - return t('files', 'Leave this share'); + return t('files_external_ethswarm', 'Leave this share'); } - return t('files', 'Leave these shares'); + return t('files_external_ethswarm', 'Leave these shares'); } /** * If those nodes are all the root node of an @@ -168,29 +241,29 @@ const actionDataUnviewFile ={ */ if (canDisconnectOnly(nodes)) { if (nodes.length === 1) { - return t('files', 'Disconnect storage'); + return t('files_external_ethswarm', 'Disconnect storage'); } - return t('files', 'Disconnect storages'); + return t('files_external_ethswarm', 'Disconnect storages'); } /** * If we're only selecting files, use proper wording */ if (isAllFiles(nodes)) { if (nodes.length === 1) { - return t('files', 'Unview file'); + return t('files_external_ethswarm', 'Unview file'); } - return t('files', 'Unview files'); + return t('files_external_ethswarm', 'Unview files'); } /** * If we're only selecting folders, use proper wording */ if (isAllFolders(nodes)) { if (nodes.length === 1) { - return t('files', 'Unview folder'); + return t('files_external_ethswarm', 'Unview folder'); } - return t('files', 'Unview folders'); + return t('files_external_ethswarm', 'Unview folders'); } - return t('files', 'Unview'); + return t('files_external_ethswarm', 'Unview'); }, iconSvgInline: (nodes) => { if (canUnshareOnly(nodes)) { @@ -215,10 +288,10 @@ const actionDataUnviewFile ={ }, async exec(node, view, dir) { let message = ''; - if (node.type !== FileType.File) { - message = t('files', 'The file will be set to unview on the folder view. The file will continue to exist on the Swarm network.'); - }else if (node.type !== FileType.Folder) { - message = t('files', 'The folder will be set to unview on the folder view. All the files inside the folder will continue to exist on the Swarm network.'); + if (node.type === FileType.File) { + message = t('files_external_ethswarm', 'The file will be set to unview on the folder view. The file will continue to exist on the Swarm network.'); + }else if (node.type === FileType.Folder) { + message = t('files_external_ethswarm', 'The folder will be set to unview on the folder view. All the files inside the folder will continue to exist on the Swarm network.'); } alert(message); try { @@ -241,7 +314,8 @@ const actionDataUnviewFile ={ // TODO: update to this? logger.error('Error while deleting a file', { error, source: node.source, node }); return false; } - }, /* TODO: Batch option async execBatch(nodes, view, dir) { + }, /* TODO: Batch option + async execBatch(nodes, view, dir) { // Map each node to a promise that resolves with the result of exec(node) const promises = nodes.map(node => { // Create a promise that resolves with the result of exec(node) @@ -255,8 +329,8 @@ const actionDataUnviewFile ={ }); return Promise.all(promises); }, */ - execBatch() { - // Not currently supported. + execBatch(nodes, view) { + return Promise.all(nodes.map(node => this.exec(node, view))); }, order: 150, }; @@ -270,15 +344,16 @@ let previousPathHasSwarm = false; subscribe('files:list:updated', (data) => { console.log('Hejbit-files:list:updated'); - if (data.contents.length >= 1){ - if (previousPathHasSwarm && !data.contents[1]._data.attributes["ethswarm-node"]){ - previousPathHasSwarm = false; - window.location.reload(); - } - if (data.contents[1]._data.attributes["ethswarm-node"]){ + if (data.folder.path === '/' && previousPathHasSwarm){ + previousPathHasSwarm = false; + window.location.reload(); + } + + const ethswarmNode = data?.contents?.[0]?._data?.attributes?.["ethswarm-node"]; + if (ethswarmNode !== undefined) { + if (ethswarmNode){ previousPathHasSwarm = true; } } - });