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

Allow drag to different page #3312

Merged
merged 37 commits into from
Oct 4, 2019
Merged

Conversation

barklund
Copy link
Contributor

@barklund barklund commented Sep 20, 2019

Fixes #3311.

This PR allows editors to drag elements to other pages.

See early demo here: https://www.youtube.com/watch?v=ONFOvRF2jog

This is done by while dragging, detecting where the actual mouse cursor is relative to the current page. A highlight callback is invoked while dragging with the offset of the page currently under the cursor. If dropped above another page, a drop callback is invoked.

The callbacks then check if there even is a page in this direction and then either highlight that page or clone the element to that page respectively.

TODO

  • Allow dragging an element to another page.
  • Fix dragging for CTAs.
  • Figure out if we need dragging for Page Attachments (resolution: we don't for now).
  • Maintain proper Separation of Concerns.
  • Make sure CTA can't be moved to a page which already has a CTA.
  • Tests? Unit testing is almost impossible, but an e2e test is feasible.

_Fixes #3311._

This WIP allows editors to drag elements to neighboring pages.

This is done by while dragging, detecting where the actual mouse cursor is relative to the current page. A highlight callback is invoked while dragging with the offset of the page currently under the cursor. If dropped above a neighboring page, a drop callback is invoked.

The callbacks then check if there even is a neigbor in this direction and then either highlight that page or clone the element to that page.

It doesn't work correctly for CTA's and Page Attachments yet.

The code is also a little weirdly structured with the bulk of the logic placed in `block-draggable`, which doesn't really sound like the right place - concern-wise. Perhaps a simple renaming solves it, but perhaps a larger restructuring is in order.
@barklund barklund added Enhancement New feature or improvement of an existing one AMP Stories labels Sep 20, 2019
@barklund barklund self-assigned this Sep 20, 2019
@googlebot googlebot added the cla: yes Signed the Google CLA label Sep 20, 2019
CTA blocks have their positions defined by a different property than regular blocks, 'btnPositionLeft` rather than `positionLeft` and similarly for top. This fixes that.

Also, CTA blocks aren't allowed on the first page. This invariant is also maintained now.
@spacedmonkey
Copy link
Contributor

This PR really needs e2e tests.

I would also look rebasing and running those e2e tests against AXE for accessibility. I would look aria-grabbed and aria-dropeffect accessibility attributes. These attributes will likely need to be updated dynamically blocks move.

@spacedmonkey
Copy link
Contributor

We might want to update using the screen reader feature using speak. We might want to update these users that the drag was / wasn't successful.

@barklund
Copy link
Contributor Author

This PR really needs e2e tests.

I'm having problems getting the e2e setup to properly test these. It might be because those tests are just too power-intensive for my machine though (which is bad!).

Also, e2e's aren't meant for exhaustive testing in any way. It's an anti-pattern if e2e's are used for this. e2e should only be used for some very overall happy-path testing to ensure, that overall dragging works as expected. Unit and integration testing should be done to validate the finer things.

@swissspidy
Copy link
Collaborator

FWIW we've had issues in the past with testing dragging as Chromium/Puppeteer doesn't have the best support there.

@barklund
Copy link
Contributor Author

We might want to update using the screen reader feature using speak. We might want to update these users that the drag was / wasn't successful.

Uh, that's a simple yet interesting package. It could definitely be used here. But maybe the overall a11y of dragging should be considered in some strategy rather than hotfixes I can attempt with speak(). I don't have the knowledge required to make sure this is actually accessible and doesn't just feel like it.

@spacedmonkey
Copy link
Contributor

I don't have the knowledge required to make sure this is actually accessible and doesn't just feel like it.

I agree here, my understanding of speak in this use case is limited. Not sure what exactly the messaging should be here. Maybe we could loop in an accessibility expect for some help here.

However the aria-grabbed and aria-dropeffect accessibility attributes seem simple enough to implement here and would be a good start.

This feature is not an accessibility friendly one in the first place, as most people with accessibility needs will be using screen readers or keyboard anyway. Which is why #3330 would be better for those users.

Several locations checked if a block was allowed on a given page, including the media inserter, the shortcut handler, paste handler and now also multi-page drag handler.

All these instances have now been a) centralised and b) changed to use the built-in method of checking for allowed blocks inside another block using core block editor functionality.

This also removed the need for a specific test for the `ensureAllowedBlocksOnPaste` as it just used other functions now more specific and central to the issue.
@barklund
Copy link
Contributor Author

The recent refactor of the "is block A allowed on page B" functionality touches on a lot of extra components, that will need to be QA'ed as well: Media Inserter, Shortcuts, Paste Block.

Just FYI for future reference.

Copy link
Contributor

@spacedmonkey spacedmonkey left a comment

Choose a reason for hiding this comment

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

Really great work on the refactor to use hooks. The code is much clearer.
Just a couple of tweaks, questions and comments to be added. Otherwise, we are looking good 👍

Work noting that they are conflicts that need to be resolved.

This converts the helper function `isBlockAllowedOnPage` to the hook `useIsBlockAllowedOnPage` which ensures that selectors are properly updated once the registry changes and any component using it is properly re-rendered.

However, because some uses of `isBlockAllowedOnPage` is located in class components, the old function has only been deprecated for now, not completely removed.
Making `attributes` optional and adding unit tests for all aspects of the hook.
@barklund barklund requested a review from spacedmonkey October 3, 2019 16:56
@spacedmonkey spacedmonkey mentioned this pull request Oct 4, 2019
18 tasks
@swissspidy
Copy link
Collaborator

@spacedmonkey Could you re-review this?

@@ -52,6 +52,7 @@ import { addQueryArgs } from '@wordpress/url';
import BlockPreview from '../block-preview';
import BlockTypesList from '../block-types-list';
import { ALLOWED_TOP_LEVEL_BLOCKS } from '../../constants';
import { isBlockAllowedOnPage } from '../../helpers';
Copy link
Contributor

Choose a reason for hiding this comment

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

Why can't the hook be used here?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Because this is still a class component, not a functional one. See #2538 for explanation.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am just worried about bug coming from not using select correctly here and getting stale data.

Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't the benefit of hooks if that you put them everyone and mix and match?

Copy link
Contributor

Choose a reason for hiding this comment

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

How that isBlockAllowedOnPage is only used in Menu, I think we should get rid of the helper and move the logic to withSelect

Copy link
Collaborator

Choose a reason for hiding this comment

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

That could work yeah 👍

@spacedmonkey
Copy link
Contributor

This bug is still happening for me on the latest update.
See screencast. https://www.youtube.com/watch?v=0ZQDFQVPRYw&feature=youtu.be

@swissspidy
Copy link
Collaborator

This bug is still happening for me on the latest update.

Hmm that seems to be because the drop zone around a page is a bit bigger than the page itself, to allow for better positioning of elements.

This way it can use the new `useIsBlockAllowedOnPage` hook
@barklund
Copy link
Contributor Author

barklund commented Oct 4, 2019

This bug is still happening for me on the latest update.
See screencast. https://www.youtube.com/watch?v=0ZQDFQVPRYw&feature=youtu.be

So, the thing is, you're allowed to drop items off-page if you feel like it – but only within a certain boundary off-page. The general item drop is handled in story-block-drop-zone, and I actually think the size of the boundary is determined by the size of an element, thus via CSS - but not sure about that.

However, in this case it gets extra weird, because off-page is technically on top of another page, that you just can't move the item to. I don't know if there's an easy way to handle this, that doesn't impact too many other things and doesn't feel like a workaround and special-case-handling.

I'll look into this drop zone, and maybe limit the drop zone so it never overlaps a neighbouring page - seems like a fair restriction.

Remove last remaining usage of that function as all other components use the new `useIsBlockAllowedOnPage` hook.
Copy link
Contributor

@spacedmonkey spacedmonkey left a comment

Choose a reason for hiding this comment

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

LGTM

@swissspidy
Copy link
Collaborator

Given that the situation with the drop zone mentioned above has been around before, it can be addressed in a separate PR

@swissspidy swissspidy added this to the v1.3.1 milestone Oct 4, 2019
@swissspidy swissspidy merged commit b7b5539 into develop Oct 4, 2019
@swissspidy swissspidy deleted the feature/3311-allow-drag-to-page branch October 4, 2019 15:59
@swissspidy swissspidy modified the milestones: v1.3.1, v1.4 Oct 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Signed the Google CLA Enhancement New feature or improvement of an existing one
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow drag element to different story page
5 participants