From 7f2074a6ec59068f75dae76d31721d65e61c9673 Mon Sep 17 00:00:00 2001 From: Mo Date: Wed, 30 Nov 2022 14:37:36 -0600 Subject: [PATCH] feat: screen presentation and dismiss animations for mobile (#2073) --- .../app/javascripts/Renderer/Renderer.ts | 15 +- packages/desktop/app/stylesheets/renderer.css | 12 +- packages/web/package.json | 5 +- .../javascripts/Application/Application.ts | 6 +- .../ApplicationProvider.tsx | 0 .../ApplicationView/ApplicationView.tsx | 76 +-- .../{ApplicationView => }/CommandProvider.tsx | 0 .../ContentListView/ContentListView.tsx | 482 +++++++++--------- .../Daily/DailyContentList.tsx | 4 +- .../ContentListView/FileListItem.tsx | 6 +- .../ContentListView/NoteListItem.tsx | 11 +- .../FileContextMenuBackupOption.tsx | 2 +- .../FileContextMenu/FileMenuOptions.tsx | 4 +- .../FileDragNDropProvider.tsx | 2 +- .../FilePreview/PreviewComponent.tsx | 4 +- .../FileView/FileViewWithoutProtection.tsx | 2 +- .../LinkedItems/ItemLinkAutocompleteInput.tsx | 2 +- .../LinkedItems/LinkedItemBubble.tsx | 2 +- .../LinkedItemBubblesContainer.tsx | 4 +- .../Components/LinkedItems/LinkedItemMeta.tsx | 2 +- .../LinkedItems/LinkedItemsPanel.tsx | 2 +- .../LinkedItems/LinkedItemsSectionItem.tsx | 2 +- .../NavigationMenu/NavigationMenu.tsx | 18 +- .../NoteGroupView/MobileItemsListButton.tsx | 39 +- .../NoteGroupView/NoteGroupView.tsx | 81 +-- .../NoteView/NoteStatusIndicator.tsx | 2 +- .../Components/NoteView/NoteView.tsx | 12 +- .../NoteView/NoteViewFileDropTarget.tsx | 2 +- .../Nodes/FileComponent.tsx | 2 +- .../Plugins/ExportPlugin/ExportPlugin.ts | 4 +- .../Nodes/BubbleComponent.tsx | 4 +- .../ItemSelectionPlugin.tsx | 2 +- .../Plugins/ReadonlyPlugin/ReadonlyPlugin.tsx | 2 +- .../NoteView/SuperEditor/SuperEditor.tsx | 2 +- .../Components/NotesOptions/AddTagOption.tsx | 2 +- .../Components/NotesOptions/NotesOptions.tsx | 10 +- .../NotesOptions/SuperNoteOptions.tsx | 2 +- .../Components/PanelResizer/PanelResizer.tsx | 42 +- .../Components/Panes/AppPaneMetadata.ts | 13 + .../Components/Panes/PaneAnimator.tsx | 60 +++ .../Components/Panes/PanesSystemComponent.tsx | 342 +++++++++++++ .../ResponsivePaneProvider.tsx | 67 +-- .../PinNoteButton/PinNoteButton.tsx | 2 +- .../Panes/Security/EncryptionEnabled.tsx | 2 +- .../PanelSettingsSection.tsx | 8 +- .../QuickSettingsMenu/QuickSettingsMenu.tsx | 5 +- .../ResponsivePane/AppPaneMetadata.ts | 5 - .../ResponsivePane/ResponsivePaneContent.tsx | 28 - .../SmartViewBuilder/PredicateValue.tsx | 2 +- .../Components/Tags/Navigation.tsx | 109 ++-- .../Components/Tags/SmartViewsListItem.tsx | 7 +- .../Components/Tags/TagsListItem.tsx | 9 +- .../Components/Tags/TagsSectionAddButton.tsx | 2 +- .../src/javascripts/Constants/PrefDefaults.ts | 2 +- .../ItemList/ItemListController.ts | 14 +- .../Controllers/LinkingController.tsx | 2 +- .../Navigation/NavigationController.ts | 15 +- .../javascripts/Controllers/PaneController.ts | 152 ------ .../PaneController/PaneController.ts | 256 ++++++++++ .../Controllers/PaneController/PaneLayout.ts | 6 + .../PaneController/panesForLayout.ts | 47 ++ .../Controllers/QuickSettingsController.ts | 22 - .../Controllers/SelectedItemsController.ts | 24 +- .../Controllers/ViewControllerManager.ts | 2 +- .../src/javascripts/Hooks/useForwardedRef.tsx | 19 + .../Hooks/useIsTabletOrMobileScreen.tsx | 37 ++ packages/web/src/javascripts/Logging.ts | 2 + .../src/javascripts/Types/PanelResizedData.ts | 1 + packages/web/src/javascripts/Utils/Utils.ts | 3 + .../src/javascripts/Utils/toggleFocusMode.tsx | 20 - packages/web/src/stylesheets/_animation.scss | 4 - packages/web/src/stylesheets/_columns.scss | 39 -- packages/web/src/stylesheets/_focused.scss | 8 +- .../web/src/stylesheets/_items-column.scss | 1 - packages/web/src/stylesheets/_main.scss | 1 - packages/web/src/stylesheets/_navigation.scss | 4 + packages/web/src/stylesheets/index.css.scss | 1 - packages/web/web.webpack.dev.js | 1 - yarn.lock | 1 - 79 files changed, 1338 insertions(+), 878 deletions(-) rename packages/web/src/javascripts/Components/{ApplicationView => }/ApplicationProvider.tsx (100%) rename packages/web/src/javascripts/Components/{ApplicationView => }/CommandProvider.tsx (100%) rename packages/web/src/javascripts/Components/{FileDragNDropProvider => }/FileDragNDropProvider.tsx (99%) create mode 100644 packages/web/src/javascripts/Components/Panes/AppPaneMetadata.ts create mode 100644 packages/web/src/javascripts/Components/Panes/PaneAnimator.tsx create mode 100644 packages/web/src/javascripts/Components/Panes/PanesSystemComponent.tsx rename packages/web/src/javascripts/Components/{ResponsivePane => Panes}/ResponsivePaneProvider.tsx (69%) delete mode 100644 packages/web/src/javascripts/Components/ResponsivePane/AppPaneMetadata.ts delete mode 100644 packages/web/src/javascripts/Components/ResponsivePane/ResponsivePaneContent.tsx delete mode 100644 packages/web/src/javascripts/Controllers/PaneController.ts create mode 100644 packages/web/src/javascripts/Controllers/PaneController/PaneController.ts create mode 100644 packages/web/src/javascripts/Controllers/PaneController/PaneLayout.ts create mode 100644 packages/web/src/javascripts/Controllers/PaneController/panesForLayout.ts create mode 100644 packages/web/src/javascripts/Hooks/useForwardedRef.tsx create mode 100644 packages/web/src/javascripts/Hooks/useIsTabletOrMobileScreen.tsx delete mode 100644 packages/web/src/javascripts/Utils/toggleFocusMode.tsx delete mode 100644 packages/web/src/stylesheets/_columns.scss diff --git a/packages/desktop/app/javascripts/Renderer/Renderer.ts b/packages/desktop/app/javascripts/Renderer/Renderer.ts index 09d07c29b..224da7111 100644 --- a/packages/desktop/app/javascripts/Renderer/Renderer.ts +++ b/packages/desktop/app/javascripts/Renderer/Renderer.ts @@ -22,7 +22,7 @@ declare global { plansUrl: string purchaseUrl: string startApplication: StartApplication - zip: any + zip: unknown electronMainEvents: any } } @@ -88,15 +88,15 @@ async function configureWindow(remoteBridge: CrossProcessBridge) { /* Title bar events */ - document.getElementById('menu-btn')!.addEventListener('click', () => { + document.getElementById('menu-btn')?.addEventListener('click', () => { remoteBridge.displayAppMenu() }) - document.getElementById('min-btn')!.addEventListener('click', () => { + document.getElementById('min-btn')?.addEventListener('click', () => { remoteBridge.minimizeWindow() }) - document.getElementById('max-btn')!.addEventListener('click', async () => { + document.getElementById('max-btn')?.addEventListener('click', async () => { if (remoteBridge.isWindowMaximized()) { remoteBridge.unmaximizeWindow() } else { @@ -104,15 +104,12 @@ async function configureWindow(remoteBridge: CrossProcessBridge) { } }) - document.getElementById('close-btn')!.addEventListener('click', () => { + document.getElementById('close-btn')?.addEventListener('click', () => { remoteBridge.closeWindow() }) // For Mac inset window const sheet = document.styleSheets[0] - if (isMacOS) { - sheet.insertRule('#navigation-content { padding-top: 25px !important; }', sheet.cssRules.length) - } if (isMacOS || useSystemMenuBar) { // !important is important here because #desktop-title-bar has display: flex. @@ -141,7 +138,7 @@ window.electronMainEvents.handlePerformAutomatedBackup(() => { void window.device.downloadBackup() }) -window.electronMainEvents.handleFinishedSavingBackup((_: IpcRendererEvent, data: any) => { +window.electronMainEvents.handleFinishedSavingBackup((_: IpcRendererEvent, data: { success: boolean }) => { window.webClient.didFinishBackup(data.success) }) diff --git a/packages/desktop/app/stylesheets/renderer.css b/packages/desktop/app/stylesheets/renderer.css index d44fcbf45..b9b640592 100644 --- a/packages/desktop/app/stylesheets/renderer.css +++ b/packages/desktop/app/stylesheets/renderer.css @@ -10,18 +10,14 @@ } @media screen and (max-width: 768px) { - .mac-desktop .app-column.selected { - padding-top: 18px; + .mac-desktop .app-pane { + padding-top: 25px; } } @media screen and (min-width: 768px) { - .mac-desktop #app.collapsed-notes.collapsed-navigation #editor-column { - padding-top: 18px; - } - - .mac-desktop #app.collapsed-navigation #items-column { - padding-top: 18px; + .mac-desktop .app-pane-1 { + padding-top: 25px; } } diff --git a/packages/web/package.json b/packages/web/package.json index 512d01e88..53d5957b4 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -12,8 +12,8 @@ "build": "yarn clean && yarn copy:components && webpack --config web.webpack.prod.js && yarn tsc", "clean": "rm -fr dist", "format": "prettier --write src/javascripts", - "lint": "NODE_OPTIONS=\"--max-old-space-size=4096\" eslint src/javascripts", - "lint:fix": "NODE_OPTIONS=\"--max-old-space-size=4096\" eslint src/javascripts --fix", + "lint": "eslint src/javascripts && yarn tsc", + "lint:fix": "eslint src/javascripts --fix", "start": "webpack-dev-server --config web.webpack.dev.js", "start-secure": "yarn start --server-type https", "test": "jest --config jest.config.js --coverage", @@ -81,7 +81,6 @@ "eslint-config-prettier": "^8.5.0", "eslint-plugin-react": "^7.31.10", "eslint-plugin-react-hooks": "^4.6.0", - "html-webpack-plugin": "^5.5.0", "identity-obj-proxy": "^3.0.0", "jest": "^29.3.1", "jest-environment-jsdom": "^29.3.1", diff --git a/packages/web/src/javascripts/Application/Application.ts b/packages/web/src/javascripts/Application/Application.ts index 7d7dd0bbe..94d0ce78f 100644 --- a/packages/web/src/javascripts/Application/Application.ts +++ b/packages/web/src/javascripts/Application/Application.ts @@ -166,11 +166,13 @@ export class WebApplication extends SNApplication implements WebApplicationInter } } - publishPanelDidResizeEvent(name: string, collapsed: boolean) { + publishPanelDidResizeEvent(name: string, width: number, collapsed: boolean) { const data: PanelResizedData = { panel: name, - collapsed: collapsed, + collapsed, + width, } + this.notifyWebEvent(WebAppEvent.PanelResized, data) } diff --git a/packages/web/src/javascripts/Components/ApplicationView/ApplicationProvider.tsx b/packages/web/src/javascripts/Components/ApplicationProvider.tsx similarity index 100% rename from packages/web/src/javascripts/Components/ApplicationView/ApplicationProvider.tsx rename to packages/web/src/javascripts/Components/ApplicationProvider.tsx diff --git a/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx b/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx index 7ab931310..4531b022a 100644 --- a/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx +++ b/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx @@ -1,36 +1,31 @@ import { ApplicationGroup } from '@/Application/ApplicationGroup' import { getPlatformString } from '@/Utils' import { ApplicationEvent, Challenge, removeFromArray, WebAppEvent } from '@standardnotes/snjs' -import { PANEL_NAME_NOTES, PANEL_NAME_NAVIGATION } from '@/Constants/Constants' import { alertDialog, RouteType } from '@standardnotes/ui-services' import { WebApplication } from '@/Application/Application' -import Navigation from '@/Components/Tags/Navigation' -import NoteGroupView from '@/Components/NoteGroupView/NoteGroupView' import Footer from '@/Components/Footer/Footer' import SessionsModal from '@/Components/SessionsModal/SessionsModal' import PreferencesViewWrapper from '@/Components/Preferences/PreferencesViewWrapper' import ChallengeModal from '@/Components/ChallengeModal/ChallengeModal' import NotesContextMenu from '@/Components/NotesContextMenu/NotesContextMenu' import PurchaseFlowWrapper from '@/Components/PurchaseFlow/PurchaseFlowWrapper' -import { FunctionComponent, useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { FunctionComponent, useCallback, useEffect, useMemo, useState } from 'react' import RevisionHistoryModal from '@/Components/RevisionHistoryModal/RevisionHistoryModal' import PremiumModalProvider from '@/Hooks/usePremiumModal' import ConfirmSignoutContainer from '@/Components/ConfirmSignoutModal/ConfirmSignoutModal' import { ToastContainer } from '@standardnotes/toast' import FilePreviewModalWrapper from '@/Components/FilePreview/FilePreviewModal' -import ContentListView from '@/Components/ContentListView/ContentListView' import FileContextMenuWrapper from '@/Components/FileContextMenu/FileContextMenu' import PermissionsModalWrapper from '@/Components/PermissionsModal/PermissionsModalWrapper' -import { PanelResizedData } from '@/Types/PanelResizedData' import TagContextMenuWrapper from '@/Components/Tags/TagContextMenuWrapper' -import FileDragNDropProvider from '../FileDragNDropProvider/FileDragNDropProvider' -import ResponsivePaneProvider from '../ResponsivePane/ResponsivePaneProvider' +import FileDragNDropProvider from '../FileDragNDropProvider' +import ResponsivePaneProvider from '../Panes/ResponsivePaneProvider' import AndroidBackHandlerProvider from '@/NativeMobileWeb/useAndroidBackHandler' import ConfirmDeleteAccountContainer from '@/Components/ConfirmDeleteAccountModal/ConfirmDeleteAccountModal' import DarkModeHandler from '../DarkModeHandler/DarkModeHandler' -import ApplicationProvider from './ApplicationProvider' -import { ErrorBoundary } from '@/Utils/ErrorBoundary' -import CommandProvider from './CommandProvider' +import ApplicationProvider from '../ApplicationProvider' +import CommandProvider from '../CommandProvider' +import PanesSystemComponent from '../Panes/PanesSystemComponent' type Props = { application: WebApplication @@ -45,8 +40,6 @@ const ApplicationView: FunctionComponent = ({ application, mainApplicatio const viewControllerManager = application.getViewControllerManager() - const appColumnContainerRef = useRef(null) - useEffect(() => { const desktopService = application.getDesktopService() @@ -137,30 +130,8 @@ const ApplicationView: FunctionComponent = ({ application, mainApplicatio }, [application, onAppLaunch, onAppStart]) useEffect(() => { - const removeObserver = application.addWebEventObserver(async (eventName, data) => { - if (eventName === WebAppEvent.PanelResized) { - if (!appColumnContainerRef.current) { - return - } - - const { panel, collapsed } = data as PanelResizedData - - if (panel === PANEL_NAME_NOTES) { - if (collapsed) { - appColumnContainerRef.current.classList.add('collapsed-notes') - } else { - appColumnContainerRef.current.classList.remove('collapsed-notes') - } - } - - if (panel === PANEL_NAME_NAVIGATION) { - if (collapsed) { - appColumnContainerRef.current.classList.add('collapsed-navigation') - } else { - appColumnContainerRef.current.classList.remove('collapsed-navigation') - } - } - } else if (eventName === WebAppEvent.WindowDidFocus) { + const removeObserver = application.addWebEventObserver(async (eventName) => { + if (eventName === WebAppEvent.WindowDidFocus) { if (!(await application.isLocked())) { application.sync.sync().catch(console.error) } @@ -206,30 +177,13 @@ const ApplicationView: FunctionComponent = ({ application, mainApplicatio featuresController={viewControllerManager.featuresController} >
-
- - - - - - - -
+ + + <>