From f9f2959ad57d6c46c121f2b830d30a085c5f30aa Mon Sep 17 00:00:00 2001 From: Antonella Sgarlatta Date: Thu, 20 May 2021 13:29:59 -0300 Subject: [PATCH] fix: make context menu scrollable when there's not enough space --- .../components/NotesContextMenu.tsx | 4 +- .../ui_models/app_state/notes_state.ts | 6 +++ .../javascripts/views/notes/notes_view.ts | 50 ++++++++++++++++--- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/components/NotesContextMenu.tsx b/app/assets/javascripts/components/NotesContextMenu.tsx index 3058c035f..0582deb85 100644 --- a/app/assets/javascripts/components/NotesContextMenu.tsx +++ b/app/assets/javascripts/components/NotesContextMenu.tsx @@ -31,8 +31,8 @@ const NotesContextMenu = observer(({ appState }: Props) => { return appState.notes.contextMenuOpen ? (
void ): Promise { diff --git a/app/assets/javascripts/views/notes/notes_view.ts b/app/assets/javascripts/views/notes/notes_view.ts index 601353762..f77fd6b9a 100644 --- a/app/assets/javascripts/views/notes/notes_view.ts +++ b/app/assets/javascripts/views/notes/notes_view.ts @@ -313,18 +313,54 @@ class NotesViewCtrl extends PureViewCtrl { document.documentElement ).fontSize; const maxContextMenuHeight = parseFloat(defaultFontSize) * 20; - if (e.clientY > clientHeight - maxContextMenuHeight) { - this.application.getAppState().notes.setContextMenuPosition({ - bottom: clientHeight - e.clientY, - left: e.clientX, - }); + const footerHeight = 32; + + // Open up-bottom is default behavior + let openUpBottom = true; + + const bottomSpace = clientHeight - footerHeight - e.clientY; + const upSpace = e.clientY; + + // If not enough space to open up-bottom + if (maxContextMenuHeight > bottomSpace) { + // If there's enough space, open bottom-up + if (upSpace > maxContextMenuHeight) { + openUpBottom = false; + this.appState.notes.setContextMenuMaxHeight( + 'auto' + ); + // Else, reduce max height (menu will be scrollable) and open in whichever direction there's more space + } else { + if (upSpace > bottomSpace) { + this.appState.notes.setContextMenuMaxHeight( + upSpace - 2 + ); + openUpBottom = false; + } else { + this.appState.notes.setContextMenuMaxHeight( + bottomSpace - 2 + ); + } + } } else { - this.application.getAppState().notes.setContextMenuPosition({ + this.appState.notes.setContextMenuMaxHeight( + 'auto' + ); + } + + if (openUpBottom) { + this.appState.notes.setContextMenuPosition({ top: e.clientY, left: e.clientX, }); + } else { + this.appState.notes.setContextMenuPosition({ + bottom: clientHeight - e.clientY, + left: e.clientX, + }); } - this.application.getAppState().notes.setContextMenuOpen(true); + + this.appState.notes.setContextMenuOpen(true); } }