feat(stream): add an actions menu to each activity entry - #2838
Open
karlitschek wants to merge 2 commits into
Open
feat(stream): add an actions menu to each activity entry#2838karlitschek wants to merge 2 commits into
karlitschek wants to merge 2 commits into
Conversation
Activity entries were read-only: seeing that a file changed gave no way to act on it without leaving for the Files app and finding it again. Only third parties could contribute anything interactive, through registerSidebarAction(), and that applies to the panel as a whole rather than to a single entry. Each entry now carries an actions menu offering, where applicable: - View, opening the file in the Viewer overlay without leaving the stream - Show in Files, revealing the file inside its folder - Copy link, always putting an absolute URL on the clipboard so it stays usable elsewhere Links deliberately do not reuse the host from the activity's own link. Providers build absolute URLs out of the server's configuration rather than the current request, so an activity recorded by a background job carries overwrite.cli.url — routinely http://localhost:8080, which no browser visiting the instance can reach. Only the path is trustworthy. Where a file id is known the link is rebuilt from scratch as /f/<fileid>, which also addresses the file itself rather than the containing directory a provider link often points at, and lets the server redirect to whichever view holds it. Otherwise the provider's path is kept and re-anchored onto the origin the session is actually using. Show in Files reveals rather than opens. `/f/<fileid>` opens the file in the Viewer on arrival, because the server sets `openfile=true` for anything that is not a folder, so the link asks for `openfile=false` explicitly. Opening is what the View action is for, and one menu entry doing both is merely surprising. The copied link is left at the server's default instead: whoever receives it wants the file, not this menu's idea of how to look at the folder around it. Actions appear only when they can do something. View needs a MIME type the Viewer advertises, which is only known where previews were requested, so it is absent in the sidebar. An activity with no file behind it renders no menu at all rather than an empty one. The menu is faded out until its row is hovered, and only on devices with a pointer, so a touch user is never asked to hover to discover it. Fading rather than hiding keeps it reachable by keyboard, and the row owns the hover rule because the row owns its layout. GenericActivity already had an unused `&__actions` style block, which now has markup to match. Clipboard failures are reported rather than swallowed, including the insecure-origin case where navigator.clipboard does not exist at all. The test config gains @nextcloud/dialogs in vitest's list of inlined dependencies. It ships CSS imports that Node cannot load, which previously went unnoticed because every test touching that module mocked it; pulling it into the entry components made three unrelated suites fail to collect. Signed-off-by: Frank Karlitschek <karlitschek@users.noreply.github.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
The actions menu sat once per row, at its end. That is the wrong scope: an activity can carry several files — a bulk upload arrives as one grouped entry with a thumbnail each — so a single menu per row could only ever act on one of them, silently picking the first preview it found. It also put the menu a long way from the thing it acted on. Each thumbnail now carries its own menu, overlaid on its top corner, and the actions are scoped to that file: View uses that preview's own MIME type and path, Show in Files resolves that preview's file id, and Copy link copies that file. Each menu is named after its file, so several on one row are distinguishable rather than three identical "Actions for this activity". The overlay is absolutely positioned so adding it changes neither the size nor the spacing of the thumbnail grid, and the toggle carries its own surface because a thumbnail can be any colour and there is nothing to rely on behind it. It stays hidden until its thumbnail is hovered, faded rather than removed so it remains keyboard reachable, and only where a real pointer exists. The preview item needed `display: flex` and `line-height: 0`: the link inside is inline, so the item's box was taller than the image it wraps and the overlay anchored above the thumbnail's real top edge. Comment entries lose their menu, since they render no thumbnails to hang one on, and so do entries in the Files sidebar, which loads without previews. Both follow from attaching the actions to files rather than to rows. Signed-off-by: Frank Karlitschek <karlitschek@users.noreply.github.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Activity entries were read-only: seeing that a file changed gave no way to act on it without leaving for the Files app and finding it again. Only third parties could contribute anything interactive, through registerSidebarAction(), and that applies to the panel as a whole rather than to a single entry.
Each entry now carries an actions menu offering, where applicable:
Links deliberately do not reuse the host from the activity's own link. Providers build absolute URLs out of the server's configuration rather than the current request, so an activity recorded by a background job carries overwrite.cli.url — routinely http://localhost:8080, which no browser visiting the instance can reach. Only the path is trustworthy. Where a file id is known the link is rebuilt from scratch as /f/, which also addresses the file itself rather than the containing directory a provider link often points at, and lets the server redirect to whichever view holds it. Otherwise the provider's path is kept and re-anchored onto the origin the session is actually using.
Show in Files reveals rather than opens.
/f/<fileid>opens the file in the Viewer on arrival, because the server setsopenfile=truefor anything that is not a folder, so the link asks foropenfile=falseexplicitly. Opening is what the View action is for, and one menu entry doing both is merely surprising. The copied link is left at the server's default instead: whoever receives it wants the file, not this menu's idea of how to look at the folder around it.Actions appear only when they can do something. View needs a MIME type the Viewer advertises, which is only known where previews were requested, so it is absent in the sidebar. An activity with no file behind it renders no menu at all rather than an empty one.
The menu is faded out until its row is hovered, and only on devices with a pointer, so a touch user is never asked to hover to discover it. Fading rather than hiding keeps it reachable by keyboard, and the row owns the hover rule because the row owns its layout. GenericActivity already had an unused
&__actionsstyle block, which now has markup to match.Clipboard failures are reported rather than swallowed, including the insecure-origin case where navigator.clipboard does not exist at all.
The test config gains @nextcloud/dialogs in vitest's list of inlined dependencies. It ships CSS imports that Node cannot load, which previously went unnoticed because every test touching that module mocked it; pulling it into the entry components made three unrelated suites fail to collect.
🤖 AI (if applicable)