Skip to content

Commit

Permalink
🐛 [Attachment Forms] Maintain the mobile UI layout when the soft keyb…
Browse files Browse the repository at this point in the history
…oard opens or closes (ampproject#35908)

* Add window observer that maintains the grid layer height when the soft keyboard opens/closes

* Add missing commas

* Temporarily OK the usage of getLayoutBox()

* Move logic to amp-story instead of amp-story-grid-layer

* Set the story's height to the max seen viewport height instead of the max seen story height

* Remove unnecesary commas

* Revert amp-story-grid-layer.js

* Prevent the soft keyboard from incorrectly triggering desktop UI state changes

* Adjust draggable drawer height on viewport height change and simplify amp-story TOGGLE_UI logic

* Run onViewportResize() within a measureElement

* Move softKeyboardIsProbablyOpen logic to getUIType_()

* Remove console logs added for testing

* Add textarea to the list of element tags that can cause soft keyboard to open, and reset fixed inline height once the layout shifts away from mobile

* Add platformIsAndroid as an additional factor when determining whether the soft keyboard is open

* Remove empty else block

* Lint fix

* Remove unnecessary if guard around the TOGGLE_UI action on resize

* Remove the onResize logic that sets the height of the story inline. This removal results in the reintroduction of the issue where the layout of the story page behind the attachment shifts when the soft keyboard is open, due to the reduced viewport size. However, the removed onResize logic was preserving the story height in a way that prevents part of the story from being physically accessible in the case of mobile viewport resizes (e.g., entering split screen mode). Additionally, the logic was complex and would be somewhat difficult to reason about in the future. We may revisit this particular soft keyboard issue in the future, depending upon the attachment form usage metrics and publisher feedback

* Pull out soft keyboard logic from getUIType_() into a new androidSoftKeyboardIsProbablyOpen_() method

* Lint fixes

* Remove onViewportResize_() logic from the draggable drawer because it is unnecessary now that we do not manually alter the story height

* Remove uiState == mobile from androidSoftKeyboardIsProbablyOpen logic, and instead use the UI state within getUIType_()
  • Loading branch information
coreymasanto authored Oct 8, 2021
1 parent cc093db commit 2fe42ef
Showing 1 changed file with 36 additions and 4 deletions.
40 changes: 36 additions & 4 deletions extensions/amp-story/1.0/amp-story.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,9 @@ export class AmpStory extends AMP.BaseElement {

/** @private {?BackgroundBlur} */
this.backgroundBlur_ = null;

/** @private {?UIType} */
this.uiState_ = null;
}

/** @override */
Expand Down Expand Up @@ -365,7 +368,8 @@ export class AmpStory extends AMP.BaseElement {
this.initializePageIds_();
this.initializeStoryPlayer_();

this.storeService_.dispatch(Action.TOGGLE_UI, this.getUIType_());
this.uiState_ = this.getUIType_();
this.storeService_.dispatch(Action.TOGGLE_UI, this.uiState_);
if (this.isLandscapeSupported_()) {
this.win.document.documentElement.setAttribute(
'data-story-supports-landscape',
Expand Down Expand Up @@ -1585,12 +1589,11 @@ export class AmpStory extends AMP.BaseElement {
* @visibleForTesting
*/
onResize() {
const uiState = this.getUIType_();
this.storeService_.dispatch(Action.TOGGLE_UI, uiState);
this.uiState_ = this.getUIType_();
this.storeService_.dispatch(Action.TOGGLE_UI, this.uiState_);

const isLandscape = this.isLandscape_();
const isLandscapeSupported = this.isLandscapeSupported_();

this.setOrientationAttribute_(isLandscape, isLandscapeSupported);
}

Expand Down Expand Up @@ -1720,6 +1723,18 @@ export class AmpStory extends AMP.BaseElement {
* @private
*/
getUIType_() {
if (
this.uiState_ === UIType.MOBILE &&
this.androidSoftKeyboardIsProbablyOpen_()
) {
// The opening of the Android soft keyboard triggers a viewport resize
// that can cause the story's dimensions to appear to be those of a
// desktop. Here, we assume that the soft keyboard is open if the latest
// UI state is mobile while an input element has focus, and we then
// ensure that the UI type does not unintentionally alter.
return UIType.MOBILE;
}

if (this.platform_.isBot()) {
return UIType.VERTICAL;
}
Expand All @@ -1736,6 +1751,23 @@ export class AmpStory extends AMP.BaseElement {
return UIType.DESKTOP_ONE_PANEL;
}

/**
* Returns whether the Android soft keyboard is most likely open, as
* calculated using multiple factors. Note that this calculation will
* incorrectly return true in cases where the user has manually dismissed the
* keyboard while retaining focus on a text field.
* @return {boolean}
* @private
*/
androidSoftKeyboardIsProbablyOpen_() {
const platformIsAndroid = this.platform_.isAndroid();
const tagNamesThatTriggerKeyboard = ['INPUT', 'TEXTAREA'];
const textFieldHasFocus = tagNamesThatTriggerKeyboard.includes(
this.win.document.activeElement?.tagName
);
return platformIsAndroid && textFieldHasFocus;
}

/**
* @return {boolean} True if the screen size matches the desktop media query.
* @private
Expand Down

0 comments on commit 2fe42ef

Please sign in to comment.