-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
[RNMobile] Update image size UI control #19232
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are some suggested test cases for this PR.
WordPress iOS:
- Simultaneous uploads - steps
- Image block - Insert image from device (failing) - steps
- Image block - Insert image from device (cancel) - steps
- Image block - Add Caption - steps
- Image block - Close/Re-open post with an ongoing image upload - steps
- Image block - Close post with an ongoing image upload - steps
- Image block - Switch to classic editor with an image block in page - steps
WordPress Android:
- Simultaneous uploads - steps
- Image block - Insert image from device (failing) - steps
- Image block - Insert image from device (cancel) - steps
- Image block - Add Caption - steps
- Image block - Close/Re-open post with an ongoing image upload - steps
- Image block - Close post with an ongoing image upload - steps
- Image block - Switch to classic editor with an image block in page - steps
If you think that suggestions should be improved please edit the configuration file here. You can also modify/add test-suites to be used in the configuration.
If you are a beginner in mobile platforms follow build instructions.
@@ -17,7 +17,7 @@ function SelectControl( { | |||
const id = `inspector-select-control-${ instanceId }`; | |||
|
|||
return ( | |||
<PickerCell | |||
<CyclePickerCell |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though I did not include it in this PR yet. I am proposing that we remove PickerCell.(though Picker is still super useful!). Though PickerCell gets the BottomSheet nested menu about 80% there, it feels like a fundamental restriction of a react-native-modal Modal nested inside of another, that we will not be able to close the containing Modal before showing the child Modal without editing the underlying library. @Tug @etoledom thoughts?
One reason this might be worth doing now is in order to decouple PickerCell from Cross Platform component refactoring efforts, like seen here in SelectControl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great to me and works perfect 🎉
There's one thing I'm not sure about, maybe @pinarol and @iamthomasbishop, could give more lights:
With this PR we are changing the UX of SelectControl
. Probably not a big deal since this is the only place we are using it so far, but for future features this could be not the best approach, if there are a lot more options to choose from.
@iamthomasbishop already gave his 👍 for this UX on this particular use case.
It's also true that the current SelectControl
needs a lot of work, so this might be a good enough mid step toward a better component, but I'm unsure of the future plans. Main question is: Is it OK to replace the SelectControl UX like this or would it be better to have a different component with this UX while maintaining the current SelectControl to use in case we need it? (Still considering that PickerCell is not being removed as mentioned here.
I personally think it's fine to merge this PR, but asking here to also give awareness of the change.
const IMAGE_SIZE_THUMBNAIL = 'thumbnail'; | ||
const IMAGE_SIZE_MEDIUM = 'medium'; | ||
const IMAGE_SIZE_LARGE = 'large'; | ||
const IMAGE_SIZE_FULL_SIZE = 'full'; | ||
const DEFAULT_SIZE_SLUG = IMAGE_SIZE_LARGE; | ||
const sizeOptionLabels = { | ||
[ IMAGE_SIZE_THUMBNAIL ]: __( 'Thumbnail' ), | ||
[ IMAGE_SIZE_MEDIUM ]: __( 'Medium' ), | ||
[ IMAGE_SIZE_LARGE ]: __( 'Large' ), | ||
[ IMAGE_SIZE_FULL_SIZE ]: __( 'Full Size' ), | ||
}; | ||
const sizeOptions = map( sizeOptionLabels, ( label, option ) => ( { value: option, label } ) ); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
@etoledom Agreed, and while this is fine for the short-term, I don't even think this is the best solution for this interaction in the long-term. I don't have visibility into whether this will also change/affect other controls, but if so can we document the effects? // cc @cameronvoell |
This changes No other controls are modified at all. |
@etoledom I didn't think we were using gutenberg/packages/block-library/src/video/edit-common-settings.js Lines 58 to 66 in 99d38df
I added a new CycleSelectControl (31caac7) to use in Image Settings until we solve the nested bottom sheet menu problem. |
Nice addition! Thanks @cameronvoell 🙏
For Galleries, I've noticed here that the SelectControl is used also for Image Sizes. Probably we should sync here and have the same UX in both image sizes and gallery image sizes. |
Agreed, we probably should. |
const { align, url, height, width, alt, href, id, linkTarget, sizeSlug } = attributes; | ||
|
||
const actions = [ { label: __( 'Clear All Settings' ), onPress: this.onClearSettings } ]; | ||
|
||
const getImageSizeOptions = () => map( imageSizes, ( { label, slug } ) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's necessary to make that a function here, just computing size options should be fine:
const sizeOptions = imageSizes.map( ( { label, slug } ) => ( { value: slug, label } ) );
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, fixed here: 9e71910
const id = `inspector-select-control-${ instanceId }`; | ||
|
||
return ( | ||
<CyclePickerCell |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I see the benefit in having both a CycleSelectControl
and a CyclePickerCell
, they seem mostly identical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd prefer to keep it this way for now. It matches other Control / BottomSheet Cell pairs like ToggleControl / SwitchCell and I think there may be implications later on related to cross platform controls, where the control might become independent of where it lives in the UI. This issue has some interesting conversation on that topic #18018
...cellProps | ||
} = props; | ||
|
||
const cycleOptionValue = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A better name for this function imo would be nextOptionValue
. Cycle does indicate that the possible options form a cycle but it's hard to understand that this is returning the next one from the currently selected one.
I think readability could be improved here as well, something as simple as this would really help I think
const nextOptionValue = () => {
const selectedOptionIndex = findIndex( options, { value } );
return options[ ( selectedOptionIndex + 1 ) % options.length ].value;
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to handle the case where options is en empty array as well ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<Cell | ||
onPress={ () => onChangeValue( cycleOptionValue() ) } | ||
editable={ false } | ||
value={ options[ findIndex( options, [ 'value', value ] ) ].label } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, let's create variables with explicit names that should help improve readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change looks good, I had a few minor comments about the code but otherwise I think it's ready. I like the fact that we create a new SelectControl component for that!
@mkevins this is not urgent but could you open an issue to start a discussion about whether we want to use the same circle button for Gallery or not? I believe we should be consistent among blocks but Gallery settings are x-platform already, so let's see what we can do there. We can dive into this after finishing the upload option. |
Thanks @pinarol ! |
One consideration I have for this kind of UX is for users low bandwidth / connectivity. In earlier tests with Gallery image size options, I noticed that when I change size options, I must wait for a new file to download (each size option must be cached individually). This mean that to change sizes with a cycle picker, the user may be required to download all sizes to their device, as they cycle through them. I'm not sure how much of an issue this is, or how many users will utilize this feature with low bandwidth. Perhaps not a major issue, just wanted to note that. cc: @iamthomasbishop |
8bd9ec1
to
9e71910
Compare
Thanks for the review @Tug! Let me know if it looks like I addressed your comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
Sorry @mkevins, I totally missed this last week!
That's a great point, regarding offline or low-bandwidth situations. I wonder if there is any way to load only one size (large or full?) image behind the scenes and have the control only simulate the change? This would bring better performance for any bandwidth scenario. |
Sounds like a good option! And I believe it's possible 👍 |
Sounds good! 👍 |
@@ -357,9 +357,9 @@ export class ImageEdit extends React.Component { | |||
}, | |||
]; | |||
|
|||
const sizeOptions = map( imageSizes, ( { label, slug } ) => ( { | |||
const sizeOptions = map( imageSizes, ( { name, slug } ) => ( { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to accommodate this change - #19800
Description
Updates the mobile SelectControl (currently only used on mobile in the Image Block) to use a Cycle Button style UI (CyclePickerCell) instead of nested BottomSheets (PickerCell).
How has this been tested?
See Gutenberg-Mobile PR: wordpress-mobile/gutenberg-mobile#1574
In order to test with image urls updating correctly via api requests, this was tested in WordPress iOS and WordPress Android
Screenshots
Types of changes
Checklist: