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

feat(FileAction): add file action support #608

Merged
merged 1 commit into from Apr 4, 2023
Merged

Conversation

skjnldsv
Copy link
Contributor

@skjnldsv skjnldsv commented Mar 18, 2023

RFC: nextcloud/server#21835

interface FileActionData {
	id: string
	displayName: (files: Node[], view) => string
	iconSvgInline: (files: Node[], view) => string
	enabled?: (files: Node[], view) => boolean
	exec: (file: Node, view) => Promise<boolean>,
	execBatch?: (files: Node[], view) => Promise<boolean[]>
	order?: number,
	default?: boolean,
	inline?: (file: Node, view) => boolean,
	renderInline?: (file: Node, view) => HTMLElement,
}

@codecov

This comment was marked as resolved.

@skjnldsv skjnldsv force-pushed the feat/files-actions branch 2 times, most recently from 5a79f3c to 10cc6af Compare March 22, 2023 16:46
lib/fileAction.ts Outdated Show resolved Hide resolved
@skjnldsv
Copy link
Contributor Author

skjnldsv commented Mar 22, 2023

The default is the last thing I'm not sure of.
This is very different than what we do right now

Same for the registering, the legacy way is registering per mimetype
And registering as default is done as a secondary step

@skjnldsv
Copy link
Contributor Author

skjnldsv commented Mar 22, 2023

After a bit of thoughts, and seeing that there are very few number of actions I don't think we would really gain by splitting per mime.
Let's just have one big list and let apps register their own actions conditions

Instead of

['image/jpeg', 'image/png', ...].forEach(mime => registerAction(action, mime))

It's easier and cleaner to just do once per app

registerAction(action)

When opening the actions menu, then it would make it easy to just do something like this (which we would have to do anyway even if we group per mimes)

<template>
	<Actions>
		<ActionButton v-for="action in enabled" ... />
	</Actions>
</template>
<script>
const actions = getActions()
const enabled = actions.filter(action => action.enabled(this.file, this.currentView))
</script>

I'm guessing most enabled checks will just do string/int comparison with the file.mime and the file.permissions.
Performances should not be an issue then

@juliushaertl any opinion?

@juliushaertl
Copy link
Contributor

I think the enabled option makes sense. This way developers have one place for implementing their logic.

I'd be a bit hesitant about the boolean value for default. From the API usage perspective the difference to the current way should not matter, but both the old and new approach lack way to properly handle multiple actions registering as a default. The current approach is that the last registered wins. I'm not sure about a better approach here tough. We could also allow passing a callback here so that apps can make this dependent on file attributes (like the disabled download), but this could also be skipped I guess if we consider viewer as the preferred default opener. One use case for this would be nextcloud/viewer#1440 where we would want to open pdf files with files_pdfviewer by default, except when secure view of collabora should be used.

@skjnldsv
Copy link
Contributor Author

skjnldsv commented Mar 23, 2023

I'd be a bit hesitant about the boolean value for default. From the API usage perspective the difference to the current way should not matter, but both the old and new approach lack way to properly handle multiple actions registering as a default. The current approach is that the last registered wins. I'm not sure about a better approach here tough. We could also allow passing a callback here so that apps can make this dependent on file attributes (like the disabled download), but this could also be skipped I guess if we consider viewer as the preferred default opener. One use case for this would be nextcloud/viewer#1440 where we would want to open pdf files with files_pdfviewer by default, except when secure view of collabora should be used.

With this enabled boolean, this would be doable then.
If the enabled is false, we go to the next default.
The order would matter there, we could have

registerAction({
	id: 'pdfviewer',
	enabled(node) {
		// node mime and secureview check
		return boolean
	},
	default: true,
	order: 10,
	...
})

registerAction({
	id: 'collabora',
	enabled(node) {
		// node mime check
		return boolean
	},
	default: true,
	order: 11,
	...
})

That way we would return the first enabled default action ?

@juliushaertl
Copy link
Contributor

The only downside this has is that app developers need to align how to handle those scenarios. But as long as we don’t decide to offer preferences for default apps or actions this seems like the most reasonable option.

@skjnldsv
Copy link
Contributor Author

But as long as we don’t decide to offer preferences for default apps or actions this seems like the most reasonable option.

Could you elaborate? :)

@juliushaertl
Copy link
Contributor

Mostly about nextcloud/server#8105 (and related feature requests we frequently get for Collabora) where there could be more than one app that provides a file handler and either the admin or users would prefer having the choice about the default.

I don't think we need to have this as part of the initial API design, just something to keep in mind that this might be a topic in the future. Especially with a growing app ecosystem.

@juliushaertl
Copy link
Contributor

Thinking about this again, I'd also say that the boolean value is good and the preference could still be handled with that. Maybe we just need to clarify that "default" only means that the registering app would like to be the default, but there are no guarantees about that due to the first-wins approach at the moment.

@skjnldsv
Copy link
Contributor Author

I don't think we need to have this as part of the initial API design, just something to keep in mind that this might be a topic in the future. Especially with a growing app ecosystem.

Could be easily done afterwards if we have multiple defaults.
The first one would be used as default click, while the others are put in the menu 👍

@skjnldsv
Copy link
Contributor Author

Great!

You should know this API is already being used on the trashbin branch and is working pretty great (with a few adjustments that i'll push later) 👍 🚀

@skjnldsv skjnldsv self-assigned this Mar 28, 2023
@skjnldsv skjnldsv added the enhancement New feature or request label Mar 28, 2023
@skjnldsv
Copy link
Contributor Author

Done everyone!

Copy link
Contributor

@artonge artonge left a comment

Choose a reason for hiding this comment

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

Looks good 👍

Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
@skjnldsv skjnldsv merged commit e94b0fc into master Apr 4, 2023
8 checks passed
@delete-merged-branch delete-merged-branch bot deleted the feat/files-actions branch April 4, 2023 13:33
@skjnldsv skjnldsv mentioned this pull request Nov 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants