From 2f09f05cf097cab261e5ce888b01eaa9a4bf9190 Mon Sep 17 00:00:00 2001 From: davy-c Date: Tue, 10 Dec 2019 13:08:19 +0900 Subject: [PATCH 01/14] fix tutorials tree --- package-lock.json | 22 +-- .../Guides => }/AboutOurCommunity.md | 0 .../{WelcomePack/Templates => }/Brainstorm.md | 0 .../Templates => }/BugfixReport.md | 0 .../Playground => }/GetStarted.md | 0 .../Guides => }/KeyboardShortcuts.md | 0 .../Templates => }/MeetingNotes.md | 0 .../{WelcomePack/Guides => }/StorageGuide.md | 0 .../Playground => }/TodaysTask.md | 0 .../Templates => }/WeeklyPlanner.md | 0 src/lib/tutorials/tree.ts | 154 +++++++----------- 11 files changed, 64 insertions(+), 112 deletions(-) rename src/lib/tutorials/files/tutorials/{WelcomePack/Guides => }/AboutOurCommunity.md (100%) rename src/lib/tutorials/files/tutorials/{WelcomePack/Templates => }/Brainstorm.md (100%) rename src/lib/tutorials/files/tutorials/{WelcomePack/Templates => }/BugfixReport.md (100%) rename src/lib/tutorials/files/tutorials/{WelcomePack/Playground => }/GetStarted.md (100%) rename src/lib/tutorials/files/tutorials/{WelcomePack/Guides => }/KeyboardShortcuts.md (100%) rename src/lib/tutorials/files/tutorials/{WelcomePack/Templates => }/MeetingNotes.md (100%) rename src/lib/tutorials/files/tutorials/{WelcomePack/Guides => }/StorageGuide.md (100%) rename src/lib/tutorials/files/tutorials/{WelcomePack/Playground => }/TodaysTask.md (100%) rename src/lib/tutorials/files/tutorials/{WelcomePack/Templates => }/WeeklyPlanner.md (100%) diff --git a/package-lock.json b/package-lock.json index 1cbb2fb223..046c823536 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2929,7 +2929,7 @@ }, "util": { "version": "0.10.3", - "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "requires": { @@ -6966,7 +6966,6 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7144,7 +7143,6 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7161,7 +7159,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7178,7 +7175,6 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -7199,7 +7195,6 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -7303,7 +7298,6 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -7442,7 +7436,6 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7464,7 +7457,6 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -9292,7 +9284,6 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -9470,7 +9461,6 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -9487,7 +9477,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -9504,7 +9493,6 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -9525,7 +9513,6 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -9629,7 +9616,6 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -9768,7 +9754,6 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -9790,7 +9775,6 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -11078,7 +11062,7 @@ }, "minimist": { "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "minipass": { @@ -15208,7 +15192,7 @@ }, "readable-stream": { "version": "1.0.33", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", "integrity": "sha1-OjYN1mwbHX/UcFOJhg7aHQ9hEmw=", "requires": { "core-util-is": "~1.0.0", diff --git a/src/lib/tutorials/files/tutorials/WelcomePack/Guides/AboutOurCommunity.md b/src/lib/tutorials/files/tutorials/AboutOurCommunity.md similarity index 100% rename from src/lib/tutorials/files/tutorials/WelcomePack/Guides/AboutOurCommunity.md rename to src/lib/tutorials/files/tutorials/AboutOurCommunity.md diff --git a/src/lib/tutorials/files/tutorials/WelcomePack/Templates/Brainstorm.md b/src/lib/tutorials/files/tutorials/Brainstorm.md similarity index 100% rename from src/lib/tutorials/files/tutorials/WelcomePack/Templates/Brainstorm.md rename to src/lib/tutorials/files/tutorials/Brainstorm.md diff --git a/src/lib/tutorials/files/tutorials/WelcomePack/Templates/BugfixReport.md b/src/lib/tutorials/files/tutorials/BugfixReport.md similarity index 100% rename from src/lib/tutorials/files/tutorials/WelcomePack/Templates/BugfixReport.md rename to src/lib/tutorials/files/tutorials/BugfixReport.md diff --git a/src/lib/tutorials/files/tutorials/WelcomePack/Playground/GetStarted.md b/src/lib/tutorials/files/tutorials/GetStarted.md similarity index 100% rename from src/lib/tutorials/files/tutorials/WelcomePack/Playground/GetStarted.md rename to src/lib/tutorials/files/tutorials/GetStarted.md diff --git a/src/lib/tutorials/files/tutorials/WelcomePack/Guides/KeyboardShortcuts.md b/src/lib/tutorials/files/tutorials/KeyboardShortcuts.md similarity index 100% rename from src/lib/tutorials/files/tutorials/WelcomePack/Guides/KeyboardShortcuts.md rename to src/lib/tutorials/files/tutorials/KeyboardShortcuts.md diff --git a/src/lib/tutorials/files/tutorials/WelcomePack/Templates/MeetingNotes.md b/src/lib/tutorials/files/tutorials/MeetingNotes.md similarity index 100% rename from src/lib/tutorials/files/tutorials/WelcomePack/Templates/MeetingNotes.md rename to src/lib/tutorials/files/tutorials/MeetingNotes.md diff --git a/src/lib/tutorials/files/tutorials/WelcomePack/Guides/StorageGuide.md b/src/lib/tutorials/files/tutorials/StorageGuide.md similarity index 100% rename from src/lib/tutorials/files/tutorials/WelcomePack/Guides/StorageGuide.md rename to src/lib/tutorials/files/tutorials/StorageGuide.md diff --git a/src/lib/tutorials/files/tutorials/WelcomePack/Playground/TodaysTask.md b/src/lib/tutorials/files/tutorials/TodaysTask.md similarity index 100% rename from src/lib/tutorials/files/tutorials/WelcomePack/Playground/TodaysTask.md rename to src/lib/tutorials/files/tutorials/TodaysTask.md diff --git a/src/lib/tutorials/files/tutorials/WelcomePack/Templates/WeeklyPlanner.md b/src/lib/tutorials/files/tutorials/WeeklyPlanner.md similarity index 100% rename from src/lib/tutorials/files/tutorials/WelcomePack/Templates/WeeklyPlanner.md rename to src/lib/tutorials/files/tutorials/WeeklyPlanner.md diff --git a/src/lib/tutorials/tree.ts b/src/lib/tutorials/tree.ts index 03d64c94ae..9ee9dcac74 100644 --- a/src/lib/tutorials/tree.ts +++ b/src/lib/tutorials/tree.ts @@ -14,99 +14,67 @@ export const tutorialsTree: TutorialsNavigatorTreeItem[] = [ type: 'storage', children: [ { - label: 'Welcome Pack', - absolutePath: 'WelcomePack', - slug: 'welcome-pack', - type: 'folder', - children: [ - { - label: 'Playground', - absolutePath: 'Playground', - slug: 'playground', - type: 'folder', - children: [ - { - label: 'Get Started!', - absolutePath: 'GetStarted.md', - slug: 'get-started', - type: 'note', - children: [] - }, - { - label: "Today's Task", - absolutePath: 'TodaysTask.md', - slug: 'daily-task', - type: 'note', - children: [] - } - ] - }, - { - label: 'Guides', - absolutePath: 'Guides', - slug: 'guides', - type: 'folder', - children: [ - { - label: 'About our community', - absolutePath: 'AboutOurCommunity.md', - slug: 'community', - type: 'note', - children: [] - }, - { - label: 'Keyboard shortcuts', - absolutePath: 'KeyboardShortcuts.md', - slug: 'keyboard-shortcuts', - type: 'note', - children: [] - }, - { - label: 'Storage guide', - absolutePath: 'StorageGuide.md', - slug: 'storage-guide', - type: 'note', - children: [] - } - ] - }, - { - label: 'Templates', - absolutePath: 'Templates', - slug: 'templates', - type: 'folder', - children: [ - { - label: 'Brainstorm', - absolutePath: 'Brainstorm.md', - slug: 'brainstorm', - type: 'note', - children: [] - }, - { - label: 'Bugfix Report', - absolutePath: 'BugfixReport.md', - slug: 'bugfix-report', - type: 'note', - children: [] - }, - { - label: 'Meeting Notes', - absolutePath: 'MeetingNotes.md', - slug: 'meeting-notes', - type: 'note', - children: [] - }, - { - label: 'Weekly Planner', - absolutePath: 'WeeklyPlanner.md', - slug: 'weekly-planner', - type: 'note', - children: [] - } - ] - } - ] + label: 'Get Started!', + absolutePath: 'GetStarted.md', + slug: 'get-started', + type: 'note', + children: [] + }, + { + label: "Today's Task", + absolutePath: 'TodaysTask.md', + slug: 'daily-task', + type: 'note', + children: [] + }, + { + label: 'About our community', + absolutePath: 'AboutOurCommunity.md', + slug: 'community', + type: 'note', + children: [] + }, + { + label: 'Keyboard shortcuts', + absolutePath: 'KeyboardShortcuts.md', + slug: 'keyboard-shortcuts', + type: 'note', + children: [] + }, + { + label: 'Storage guide', + absolutePath: 'StorageGuide.md', + slug: 'storage-guide', + type: 'note', + children: [] + }, + { + label: 'Template - Brainstorm', + absolutePath: 'Brainstorm.md', + slug: 'brainstorm', + type: 'note', + children: [] + }, + { + label: 'Template - Bugfix Report', + absolutePath: 'BugfixReport.md', + slug: 'bugfix-report', + type: 'note', + children: [] + }, + { + label: 'Template - Meeting Notes', + absolutePath: 'MeetingNotes.md', + slug: 'meeting-notes', + type: 'note', + children: [] + }, + { + label: 'Template - Weekly Planner', + absolutePath: 'WeeklyPlanner.md', + slug: 'weekly-planner', + type: 'note', + children: [] } ] } From 45418e90ed10194e65a5b902c0a073bfb6e3516a Mon Sep 17 00:00:00 2001 From: davy-c Date: Tue, 10 Dec 2019 13:10:57 +0900 Subject: [PATCH 02/14] redirect to create storage page --- src/lib/router/redirect.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/lib/router/redirect.ts b/src/lib/router/redirect.ts index 51e0828ff9..94f345793c 100644 --- a/src/lib/router/redirect.ts +++ b/src/lib/router/redirect.ts @@ -1,24 +1,18 @@ import { useDb } from '../db' import { useRouter } from './store' import { useEffect } from 'react' -import { usePreferences } from '../preferences' export default function useRedirectHandler() { const db = useDb() - const { preferences } = usePreferences() const { push, pathname } = useRouter() useEffect(() => { if (!db.initialized || db.storageMap == null) { return } - if ( - pathname === '/app' && - preferences['general.tutorials'] === 'display' && - Object.keys(db.storageMap).length === 0 - ) { - push('/app/tutorials/welcome-pack/guides/notes/note:storage-guide') + if (pathname === '/app' && Object.keys(db.storageMap).length === 0) { + push('/app/storages') } return - }, [pathname, db.initialized, preferences['general.displayTutorials']]) + }, [pathname, db.initialized]) } From 1522e6a3f3da234f9eb956f817f6cfd2911e2451 Mon Sep 17 00:00:00 2001 From: davy-c Date: Tue, 10 Dec 2019 19:42:09 +0900 Subject: [PATCH 03/14] context menu to hide tutorials --- .../Tutorials/TutorialsNavigator.tsx | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/components/Tutorials/TutorialsNavigator.tsx b/src/components/Tutorials/TutorialsNavigator.tsx index cf7143903b..ec10d9601d 100644 --- a/src/components/Tutorials/TutorialsNavigator.tsx +++ b/src/components/Tutorials/TutorialsNavigator.tsx @@ -12,6 +12,9 @@ import { currentTutorialPathname } from '../../lib/router' import { useGeneralStatus } from '../../lib/generalStatus' +import { useContextMenu, MenuTypes } from '../../lib/contextMenu' +import { useDialog, DialogIconTypes } from '../../lib/dialog' +import { usePreferences } from '../../lib/preferences' interface NavigatorNode { id: string @@ -29,7 +32,10 @@ const TutorialsNavigator = ({ }: TutorialsNavigatorProps) => { const routeParams = useRouteParams() const { push } = useRouter() const currentHref = currentTutorialPathname() + const { popup } = useContextMenu() + const { messageBox } = useDialog() const { toggleSideNavOpenedItem, sideNavOpenedItemSet } = useGeneralStatus() + const { setPreferences } = usePreferences() const tutorials = tutorialsTree @@ -95,6 +101,33 @@ const TutorialsNavigator = ({ }: TutorialsNavigatorProps) => { } } + const createOnContextMenuHandler = (depth: number) => { + return (event: React.MouseEvent) => { + event.preventDefault() + popup(event, [ + { + type: MenuTypes.Normal, + label: 'Remove folder', + enabled: depth === 0, + onClick: () => { + messageBox({ + title: `Hide tutorials`, + message: + 'You can choose to display them again in your preferences.', + iconType: DialogIconTypes.Warning, + buttons: ['Hide', 'Cancel'], + defaultButtonIndex: 0, + cancelButtonIndex: 1, + onClose: () => { + setPreferences({ 'general.tutorials': 'hide' }) + } + }) + } + } + ]) + } + } + const nodes = useMemo(() => { return tutorials .map(tutorial => getNavigatorNodesFromTreeItem(tutorial, 0)) @@ -122,6 +155,7 @@ const TutorialsNavigator = ({ }: TutorialsNavigatorProps) => { onClick={() => redirectToTutorialNode(node)} onFoldButtonClick={() => toggleSideNavOpenedItem(node.id)} folded={node.children.length === 0 ? undefined : !node.opened} + onContextMenu={createOnContextMenuHandler(node.depth)} /> {node.children.map(child => renderNode(child, node.opened))} From f67e34ad40551404a4d3b1f10450fd2023c562f1 Mon Sep 17 00:00:00 2001 From: davy-c Date: Tue, 10 Dec 2019 19:56:55 +0900 Subject: [PATCH 04/14] change padding of no storage --- src/components/SideNavigator/SideNavigator.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/SideNavigator/SideNavigator.tsx b/src/components/SideNavigator/SideNavigator.tsx index fbc1d575ca..bc11203460 100644 --- a/src/components/SideNavigator/SideNavigator.tsx +++ b/src/components/SideNavigator/SideNavigator.tsx @@ -67,8 +67,11 @@ const StyledSideNavContainer = styled.nav` display: flex; flex-direction: column; } + .empty { padding: 4px; + padding-left: 26px; + margin-bottom: 4px; user-select: none; } From ed92c70d1339b507d98112bfb0f5cdc4047d1c71 Mon Sep 17 00:00:00 2001 From: davy-c Date: Tue, 10 Dec 2019 20:05:41 +0900 Subject: [PATCH 05/14] text color for no storage --- src/components/SideNavigator/SideNavigator.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/SideNavigator/SideNavigator.tsx b/src/components/SideNavigator/SideNavigator.tsx index bc11203460..87a4fb0248 100644 --- a/src/components/SideNavigator/SideNavigator.tsx +++ b/src/components/SideNavigator/SideNavigator.tsx @@ -19,7 +19,8 @@ import { usePreferences } from '../../lib/preferences' import { backgroundColor, iconColor, - textColor + textColor, + uiTextColor } from '../../lib/styled/styleFunctions' import SideNavigatorItem from './SideNavigatorItem' import { useGeneralStatus } from '../../lib/generalStatus' @@ -72,6 +73,7 @@ const StyledSideNavContainer = styled.nav` padding: 4px; padding-left: 26px; margin-bottom: 4px; + ${uiTextColor} user-select: none; } From df0678f4edaec8467e84f2d1d4b5f0fb3cebdafc Mon Sep 17 00:00:00 2001 From: davy-c Date: Wed, 11 Dec 2019 13:42:56 +0900 Subject: [PATCH 06/14] tmp --- src/components/App.tsx | 5 +++ src/components/Modals/index.tsx | 76 +++++++++++++++++++++++++++++++++ src/components/Modals/styled.ts | 64 +++++++++++++++++++++++++++ src/index.tsx | 4 +- src/lib/modals/index.tsx | 2 + src/lib/modals/loadModals.ts | 23 ++++++++++ src/lib/modals/store.ts | 26 +++++++++++ src/lib/modals/types.ts | 14 ++++++ 8 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 src/components/Modals/index.tsx create mode 100644 src/components/Modals/styled.ts create mode 100644 src/lib/modals/index.tsx create mode 100644 src/lib/modals/loadModals.ts create mode 100644 src/lib/modals/store.ts create mode 100644 src/lib/modals/types.ts diff --git a/src/components/App.tsx b/src/components/App.tsx index 3a61c1de81..c0fb11ad4d 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -16,6 +16,8 @@ import '../lib/i18n' import '../lib/analytics' import CodeMirrorStyle from './CodeMirrorStyle' import { useGeneralStatus } from '../lib/generalStatus' +import Modals from './Modals' +import useLoadModalsHandler from '../lib/modals/loadModals' const App = () => { const { initialize, initialized } = useDb() @@ -46,6 +48,8 @@ const App = () => { [setGeneralStatus] ) + useLoadModalsHandler() + return ( { + diff --git a/src/components/Modals/index.tsx b/src/components/Modals/index.tsx new file mode 100644 index 0000000000..78caa4649f --- /dev/null +++ b/src/components/Modals/index.tsx @@ -0,0 +1,76 @@ +import React, { useMemo, useCallback } from 'react' +import { useGlobalKeyDownHandler } from '../../lib/keyboard' +import { useModals } from '../../lib/modals/store' +import { + StyledModalsBackground, + StyledModalsContainer, + StyledModalsSkipButton +} from './styled' +import Icon from '../atoms/Icon' +import { mdiChevronRightCircleOutline } from '@mdi/js' + +interface ModalsRenderingOptions { + closable: boolean + body: JSX.Element + onSkip?: () => void +} + +export default () => { + const { modalsContent, closeModals } = useModals() + + if (modalsContent == null) return null + + const content = useMemo((): ModalsRenderingOptions => { + let basicModal: ModalsRenderingOptions = { + closable: true, + body: <> + } + + switch (modalsContent) { + case 'download-app': + basicModal.body = hey + break + default: + break + } + + return basicModal + }, [modalsContent]) + + const closeHandler = useCallback(() => { + if (content.onSkip != null) { + return content.onSkip() + } + return closeModals() + }, [content]) + + const keydownHandler = useMemo(() => { + return (event: KeyboardEvent) => { + if (!closed && event.key === 'Escape' && content.closable) { + closeHandler() + } + } + }, [closeHandler]) + useGlobalKeyDownHandler(keydownHandler) + + const backgroundClickHandler = useMemo(() => { + if (!content.closable) { + return null + } + return closeHandler() + }, [closeHandler]) + + return ( + + + {content.body} + + {content.closable && ( + + Skip + + )} + + + ) +} diff --git a/src/components/Modals/styled.ts b/src/components/Modals/styled.ts new file mode 100644 index 0000000000..62e3637558 --- /dev/null +++ b/src/components/Modals/styled.ts @@ -0,0 +1,64 @@ +import styled from '../../lib/styled' +import { + border, + backgroundColor, + contextMenuShadow, + iconColor +} from '../../lib/styled/styleFunctions' + +const zIndexModalsBackground = 8001 + +export const StyledModalsBackground = styled.div` + z-index: ${zIndexModalsBackground}; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + ${backgroundColor}; + opacity: 0.8; + display: flex; + overflow: hidden; +` + +export const StyledModalsContainer = styled.div` + z-index: ${zIndexModalsBackground + 1}; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: auto; + width: 50vw; + height: 60vh; + ${border} + ${backgroundColor} + ${contextMenuShadow} + border-radius: 4px; + display: flex; + overflow: hidden; +` + +export const StyledModalsHeader = styled.h1` + margin: 0; + padding: 1em 0; +` + +export const StyledModalsSkipButton = styled.button` + position: absolute; + bottom: 0; + right: 30px; + width: 40px; + height: 40px; + background-color: transparent; + border: none; + font-size: 16px; + white-space: nowrap; + cursor: pointer; + ${iconColor} + + .icon { + display: inline-block; + vertical-align: middle; + } +` diff --git a/src/index.tsx b/src/index.tsx index f27bba7fd0..1a9d3d5c71 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -9,6 +9,7 @@ import { DbProvider } from './lib/db' import { PreferencesProvider } from './lib/preferences' import { GeneralStatusProvider } from './lib/generalStatus' import { PreviewStyleProvider } from './lib/preview' +import { ModalsProvider } from './lib/modals' const CombinedProvider = combineProviders( PreviewStyleProvider, @@ -17,7 +18,8 @@ const CombinedProvider = combineProviders( DialogProvider, ContextMenuProvider, DbProvider, - RouterProvider + RouterProvider, + ModalsProvider ) function render(Component: typeof App) { diff --git a/src/lib/modals/index.tsx b/src/lib/modals/index.tsx new file mode 100644 index 0000000000..d713e08ccc --- /dev/null +++ b/src/lib/modals/index.tsx @@ -0,0 +1,2 @@ +export * from './types' +export * from './store' diff --git a/src/lib/modals/loadModals.ts b/src/lib/modals/loadModals.ts new file mode 100644 index 0000000000..6db47af9b5 --- /dev/null +++ b/src/lib/modals/loadModals.ts @@ -0,0 +1,23 @@ +import { useDb } from '../db' +import { useRouter } from '../router/store' +import { useEffect } from 'react' +import { useModals } from './store' + +export default function useLoadModalsHandler() { + const db = useDb() + const { pathname } = useRouter() + const { setModalsContent } = useModals() + + useEffect(() => { + if (!db.initialized || db.storageMap == null) { + return + } + if ( + pathname === '/app/storages' && + Object.keys(db.storageMap).length === 0 + ) { + setModalsContent('download-app') + } + return + }, [pathname, db.initialized]) +} diff --git a/src/lib/modals/store.ts b/src/lib/modals/store.ts new file mode 100644 index 0000000000..1c3d7916bf --- /dev/null +++ b/src/lib/modals/store.ts @@ -0,0 +1,26 @@ +import { useState, useCallback } from 'react' +import { ModalsContentOptions, ModalsContext } from './types' +import { createStoreContext } from '../utils/context' +export * from './types' + +function useModalsStore(): ModalsContext { + const [ + modalsContent, + setModalsContent + ] = useState(null) + + const closeModals = useCallback(() => { + setModalsContent(null) + }, []) + + return { + modalsContent, + closeModals, + setModalsContent + } +} + +export const { + StoreProvider: ModalsProvider, + useStore: useModals +} = createStoreContext(useModalsStore, 'modals') diff --git a/src/lib/modals/types.ts b/src/lib/modals/types.ts new file mode 100644 index 0000000000..0ceaddee8f --- /dev/null +++ b/src/lib/modals/types.ts @@ -0,0 +1,14 @@ +export type ModalsContentOptions = 'download-app' + +export interface ModalsRenderingOptions { + closable: boolean + skippable: boolean + onClose?(): void + body: JSX.Element +} + +export interface ModalsContext { + modalsContent: ModalsContentOptions | null + setModalsContent(options: ModalsContentOptions): void + closeModals(): void +} From 0ccc394fc0fba20f2462db728a68f92c204af735 Mon Sep 17 00:00:00 2001 From: davy-c Date: Wed, 11 Dec 2019 16:56:14 +0900 Subject: [PATCH 07/14] fix lint command --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 046c823536..07a6432528 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6015,9 +6015,9 @@ } }, "eslint-plugin-react-hooks": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.0.1.tgz", - "integrity": "sha512-xir+3KHKo86AasxlCV8AHRtIZPHljqCRRUYgASkbatmt0fad4+5GgC7zkT7o/06hdKM6MIwp8giHVXqBPaarHQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.3.0.tgz", + "integrity": "sha512-gLKCa52G4ee7uXzdLiorca7JIQZPPXRAQDXV83J4bUEeUuc5pIEyZYAZ45Xnxe5IuupxEqHS+hUhSLIimK1EMw==", "dev": true }, "eslint-scope": { diff --git a/package.json b/package.json index 7123427d77..d9b795f1c3 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "eslint-config-prettier": "^6.3.0", "eslint-plugin-prettier": "^3.1.1", "eslint-plugin-react": "^7.14.3", - "eslint-plugin-react-hooks": "^2.0.1", + "eslint-plugin-react-hooks": "^2.3.0", "html-webpack-plugin": "^3.2.0", "jest": "^24.9.0", "json-loader": "^0.5.7", From afff84b63fca0fa7eb91f3377cbd7622c13e01f3 Mon Sep 17 00:00:00 2001 From: davy-c Date: Wed, 11 Dec 2019 17:00:28 +0900 Subject: [PATCH 08/14] first lint fixes --- .../Tutorials/TutorialsNavigator.tsx | 129 ++++++------ src/components/Tutorials/TutorialsPage.tsx | 191 ++++++++---------- src/lib/download.ts | 2 +- 3 files changed, 151 insertions(+), 171 deletions(-) diff --git a/src/components/Tutorials/TutorialsNavigator.tsx b/src/components/Tutorials/TutorialsNavigator.tsx index ec10d9601d..0f4adadce4 100644 --- a/src/components/Tutorials/TutorialsNavigator.tsx +++ b/src/components/Tutorials/TutorialsNavigator.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from 'react' +import React, { useMemo, useCallback } from 'react' import { tutorialsTree, TutorialsNavigatorTreeItem } from '../../lib/tutorials' import SideNavigatorItem from '../SideNavigator/SideNavigatorItem' import { @@ -6,11 +6,7 @@ import { mdiFolderOutline, mdiHelpCircleOutline } from '@mdi/js' -import { - useRouteParams, - useRouter, - currentTutorialPathname -} from '../../lib/router' +import { useRouter, useCurrentTutorialPathname } from '../../lib/router' import { useGeneralStatus } from '../../lib/generalStatus' import { useContextMenu, MenuTypes } from '../../lib/contextMenu' import { useDialog, DialogIconTypes } from '../../lib/dialog' @@ -26,12 +22,10 @@ interface NavigatorNode { children: NavigatorNode[] active?: boolean } -interface TutorialsNavigatorProps {} -const TutorialsNavigator = ({ }: TutorialsNavigatorProps) => { - const routeParams = useRouteParams() +const TutorialsNavigator = ({}) => { const { push } = useRouter() - const currentHref = currentTutorialPathname() + const currentHref = useCurrentTutorialPathname() const { popup } = useContextMenu() const { messageBox } = useDialog() const { toggleSideNavOpenedItem, sideNavOpenedItemSet } = useGeneralStatus() @@ -39,67 +33,70 @@ const TutorialsNavigator = ({ }: TutorialsNavigatorProps) => { const tutorials = tutorialsTree - function getNavigatorNodesFromTreeItem( - tree: TutorialsNavigatorTreeItem, - currentDepth: number, - parentNode?: NavigatorNode, - parentComponentPathname?: string - ): NavigatorNode | undefined { - if (tree.type === 'note') { - return - } + const getNavigatorNodesFromTreeItem = useCallback( + ( + tree: TutorialsNavigatorTreeItem, + currentDepth: number, + parentNode?: NavigatorNode, + parentComponentPathname?: string + ): NavigatorNode | undefined => { + if (tree.type === 'note') { + return + } - const componentPathname = `${parentComponentPathname != null && - parentComponentPathname}/${tree.absolutePath}` - const nodeHref = `${parentNode != null ? parentNode.href : '/app'}/${ - tree.slug - }` + const componentPathname = `${parentComponentPathname != null && + parentComponentPathname}/${tree.absolutePath}` + const nodeHref = `${parentNode != null ? parentNode.href : '/app'}/${ + tree.slug + }` - const folderIsActive = currentHref.split('/notes/note:')[0] === nodeHref + const folderIsActive = currentHref.split('/notes/note:')[0] === nodeHref - const notesUnderCurrentNode = tree.children.filter( - child => child.type === 'note' - ) + const notesUnderCurrentNode = tree.children.filter( + child => child.type === 'note' + ) - const nodeId = `TF-${nodeHref.split('/app')[1]}` - const currentNode = { - id: nodeId, - name: `${tree.label} ${ - notesUnderCurrentNode.length > 0 - ? `(${notesUnderCurrentNode.length})` - : '' - }`, - iconPath: - tree.type === 'folder' - ? folderIsActive - ? mdiFolderOpenOutline - : mdiFolderOutline - : mdiHelpCircleOutline, - href: nodeHref, - active: folderIsActive, - depth: currentDepth, - opened: sideNavOpenedItemSet.has(nodeId), - children: [] - } + const nodeId = `TF-${nodeHref.split('/app')[1]}` + const currentNode = { + id: nodeId, + name: `${tree.label} ${ + notesUnderCurrentNode.length > 0 + ? `(${notesUnderCurrentNode.length})` + : '' + }`, + iconPath: + tree.type === 'folder' + ? folderIsActive + ? mdiFolderOpenOutline + : mdiFolderOutline + : mdiHelpCircleOutline, + href: nodeHref, + active: folderIsActive, + depth: currentDepth, + opened: sideNavOpenedItemSet.has(nodeId), + children: [] + } - const childrenNodes = - tree.children.length === 0 - ? [] - : (tree.children - .map(childrenTree => - getNavigatorNodesFromTreeItem( - childrenTree, - currentDepth + 1, - currentNode, - componentPathname + const childrenNodes = + tree.children.length === 0 + ? [] + : (tree.children + .map(childrenTree => + getNavigatorNodesFromTreeItem( + childrenTree, + currentDepth + 1, + currentNode, + componentPathname + ) ) - ) - .filter(node => node != null) as NavigatorNode[]) - return { - ...currentNode, - children: childrenNodes - } - } + .filter(node => node != null) as NavigatorNode[]) + return { + ...currentNode, + children: childrenNodes + } + }, + [currentHref, sideNavOpenedItemSet] + ) const createOnContextMenuHandler = (depth: number) => { return (event: React.MouseEvent) => { @@ -132,7 +129,7 @@ const TutorialsNavigator = ({ }: TutorialsNavigatorProps) => { return tutorials .map(tutorial => getNavigatorNodesFromTreeItem(tutorial, 0)) .filter(node => node != null) as NavigatorNode[] - }, [routeParams, tutorials, toggleSideNavOpenedItem]) + }, [tutorials, getNavigatorNodesFromTreeItem]) const redirectToTutorialNode = (node: NavigatorNode) => { push(node.href) diff --git a/src/components/Tutorials/TutorialsPage.tsx b/src/components/Tutorials/TutorialsPage.tsx index 067283ea83..4543c6fe16 100644 --- a/src/components/Tutorials/TutorialsPage.tsx +++ b/src/components/Tutorials/TutorialsPage.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useCallback, useState } from 'react' +import React, { useCallback, useMemo } from 'react' import { tutorialsTree, TutorialsNavigatorTreeItem } from '../../lib/tutorials' import TwoPaneLayout from '../atoms/TwoPaneLayout' import { useGeneralStatus } from '../../lib/generalStatus' @@ -16,20 +16,89 @@ type TutoriasPagePicker = { } export default ({ pathname }: TutorialsPageProps) => { - const [ - currentTutorialBranch, - setCurrentTutorialBranch - ] = useState(getCurrentNodeFromTutorialTrees) + const { generalStatus, setGeneralStatus } = useGeneralStatus() + const router = useRouter() + + const searchThroughTreeForIdenticalNode = useCallback( + ( + pathToSearch: string, + parentDepthPath: string, + parentAbsolutePath: string, + tree: TutorialsNavigatorTreeItem, + parentTree?: TutorialsNavigatorTreeItem + ): TutoriasPagePicker | null => { + let match = null + const currentDepthPath = `${parentDepthPath}/${ + tree.type === 'note' ? 'notes/note:' : '' + }${tree.slug}` + + const currentAbsolutePath = parentAbsolutePath + '/' + tree.absolutePath + if (currentDepthPath === pathToSearch) { + const currentTreeWithDepthAbsolutePath = { + ...tree, + absolutePath: currentAbsolutePath, + children: Object.entries(tree.children).map(obj => { + return { + ...obj[1], + absolutePath: currentAbsolutePath + '/' + obj[1].absolutePath + } + }) as TutorialsNavigatorTreeItem[] + } + + const parentTreeWithDepthAbsolutePath = + parentTree != null + ? { + ...parentTree, + absolutePath: parentAbsolutePath, + children: Object.entries(parentTree.children).map(obj => { + return { + ...obj[1], + absolutePath: parentAbsolutePath + '/' + obj[1].absolutePath + } + }) + } + : undefined + + return { + currentTree: currentTreeWithDepthAbsolutePath, + parentTree: parentTreeWithDepthAbsolutePath + } + } + + for (let i = 0; i < tree.children.length; i++) { + match = searchThroughTreeForIdenticalNode( + pathToSearch, + currentDepthPath, + currentAbsolutePath, + tree.children[i], + tree + ) + if (match != null) { + break + } + } - const [currentFolderPathname, setCurrentFolderPathname] = useState( - getCurrentFolderPathname + return match + }, + [] ) - const [selectedNote, setSelectedNote] = useState< - TutorialsNavigatorTreeItem | undefined - >() - const { generalStatus, setGeneralStatus } = useGeneralStatus() - const router = useRouter() + const currentTutorialBranch = useMemo(() => { + let match = null + for (let i = 0; i < tutorialsTree.length; i++) { + match = searchThroughTreeForIdenticalNode( + pathname, + '/app', + '', + tutorialsTree[i] + ) + if (match != null) { + break + } + } + return match + }, [pathname, searchThroughTreeForIdenticalNode]) + const updateNoteListWidth = useCallback( (leftWidth: number) => { setGeneralStatus({ @@ -51,16 +120,7 @@ export default ({ pathname }: TutorialsPageProps) => { })) }, [setGeneralStatus]) - useEffect(() => { - setCurrentTutorialBranch(getCurrentNodeFromTutorialTrees) - setCurrentFolderPathname(getCurrentFolderPathname) - }, [pathname, tutorialsTree]) - - useEffect(() => { - setSelectedNote(getCurrentNote) - }, [currentTutorialBranch]) - - function getCurrentNote(): TutorialsNavigatorTreeItem | undefined { + const selectedNote = useMemo((): TutorialsNavigatorTreeItem | undefined => { if (currentTutorialBranch == null) { return undefined } @@ -76,88 +136,11 @@ export default ({ pathname }: TutorialsPageProps) => { return notesChildren[0] } return undefined - } + }, [currentTutorialBranch]) - function getCurrentFolderPathname() { + const currentFolderPathname = useMemo(() => { return pathname.split('/notes')[0] - } - - function getCurrentNodeFromTutorialTrees() { - let match = null - for (let i = 0; i < tutorialsTree.length; i++) { - match = searchThroughTreeForIdenticalNode( - pathname, - '/app', - '', - tutorialsTree[i] - ) - if (match != null) { - break - } - } - return match - } - - function searchThroughTreeForIdenticalNode( - pathToSearch: string, - parentDepthPath: string, - parentAbsolutePath: string, - tree: TutorialsNavigatorTreeItem, - parentTree?: TutorialsNavigatorTreeItem - ): TutoriasPagePicker | null { - let match = null - const currentDepthPath = `${parentDepthPath}/${ - tree.type === 'note' ? 'notes/note:' : '' - }${tree.slug}` - - const currentAbsolutePath = parentAbsolutePath + '/' + tree.absolutePath - if (currentDepthPath === pathToSearch) { - const currentTreeWithDepthAbsolutePath = { - ...tree, - absolutePath: currentAbsolutePath, - children: Object.entries(tree.children).map(obj => { - return { - ...obj[1], - absolutePath: currentAbsolutePath + '/' + obj[1].absolutePath - } - }) as TutorialsNavigatorTreeItem[] - } - - const parentTreeWithDepthAbsolutePath = - parentTree != null - ? { - ...parentTree, - absolutePath: parentAbsolutePath, - children: Object.entries(parentTree.children).map(obj => { - return { - ...obj[1], - absolutePath: parentAbsolutePath + '/' + obj[1].absolutePath - } - }) - } - : undefined - - return { - currentTree: currentTreeWithDepthAbsolutePath, - parentTree: parentTreeWithDepthAbsolutePath - } - } - - for (let i = 0; i < tree.children.length; i++) { - match = searchThroughTreeForIdenticalNode( - pathToSearch, - currentDepthPath, - currentAbsolutePath, - tree.children[i], - tree - ) - if (match != null) { - break - } - } - - return match - } + }, [pathname]) const navigateUp = useCallback(() => { if (currentTutorialBranch == null) { @@ -199,7 +182,7 @@ export default ({ pathname }: TutorialsPageProps) => { ) } return - }, [selectedNote]) + }, [selectedNote, currentTutorialBranch, router, currentFolderPathname]) const navigateDown = useCallback(() => { if (currentTutorialBranch == null) { @@ -241,7 +224,7 @@ export default ({ pathname }: TutorialsPageProps) => { ) } return - }, [selectedNote]) + }, [selectedNote, currentFolderPathname, currentTutorialBranch, router]) return ( Date: Wed, 11 Dec 2019 19:34:23 +0900 Subject: [PATCH 09/14] Modal Provider and download app modal --- resources/Desktop.svg | 44 +++++++++++ resources/Mobile.svg | 79 +++++++++++++++++++ src/components/App.tsx | 3 - .../Modals/contents/DownloadOurAppModal.tsx | 38 +++++++++ src/components/Modals/contents/styled.ts | 79 +++++++++++++++++++ src/components/Modals/index.tsx | 40 +++++++--- src/components/Modals/styled.ts | 12 ++- src/components/Router.tsx | 3 + src/index.tsx | 6 +- src/lib/modals/index.tsx | 1 + src/lib/modals/loadModals.ts | 23 ------ src/lib/modals/loadModalsOnRouteChange.ts | 23 ++++++ src/lib/modals/store.ts | 8 +- src/lib/modals/types.ts | 4 +- src/lib/preferences/store.ts | 1 + src/lib/preferences/types.ts | 1 + src/lib/router/redirect.ts | 6 +- src/lib/router/utils.ts | 2 +- 18 files changed, 317 insertions(+), 56 deletions(-) create mode 100644 resources/Desktop.svg create mode 100644 resources/Mobile.svg create mode 100644 src/components/Modals/contents/DownloadOurAppModal.tsx create mode 100644 src/components/Modals/contents/styled.ts delete mode 100644 src/lib/modals/loadModals.ts create mode 100644 src/lib/modals/loadModalsOnRouteChange.ts diff --git a/resources/Desktop.svg b/resources/Desktop.svg new file mode 100644 index 0000000000..33462d45be --- /dev/null +++ b/resources/Desktop.svg @@ -0,0 +1,44 @@ + + + + Macbook Pro + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/Mobile.svg b/resources/Mobile.svg new file mode 100644 index 0000000000..5aed769403 --- /dev/null +++ b/resources/Mobile.svg @@ -0,0 +1,79 @@ + + + + Group 8 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/App.tsx b/src/components/App.tsx index c0fb11ad4d..ff998975a8 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -17,7 +17,6 @@ import '../lib/analytics' import CodeMirrorStyle from './CodeMirrorStyle' import { useGeneralStatus } from '../lib/generalStatus' import Modals from './Modals' -import useLoadModalsHandler from '../lib/modals/loadModals' const App = () => { const { initialize, initialized } = useDb() @@ -48,8 +47,6 @@ const App = () => { [setGeneralStatus] ) - useLoadModalsHandler() - return ( { + return ( + + Download our apps + + Use Boostnote on your local and focus on your work! + + + +
+ + +
+
+ + + + We are planning for a launch by the end of the year. + +
+
+
+
+ ) +} + +export default DownloadOurAppModal diff --git a/src/components/Modals/contents/styled.ts b/src/components/Modals/contents/styled.ts new file mode 100644 index 0000000000..207bd4ed13 --- /dev/null +++ b/src/components/Modals/contents/styled.ts @@ -0,0 +1,79 @@ +import styled from '../../../lib/styled' +import { textColor } from '../../../lib/styled/styleFunctions' + +export const ModalContainer = styled.div` + width: 100%; + ${textColor} + padding: 3px; +` + +export const ModalHeader = styled.h1` + text-align: center; + margin-top: 10px; + margin-bottom: 10px; +` + +export const ModalSubtitle = styled.h4` + text-align: center; + margin-bottom: 8vh; +` + +export const ModalBody = styled.div` + margin-top: 20px; + padding: 0 2%; + + .button { + display: block; + background-color: rgb(3, 197, 136); + font-size: 16px; + line-height: 1; + text-transform: uppercase; + color: rgb(255, 255, 255); + padding: 16px 32px; + border-width: initial; + border-style: none; + border-color: initial; + border-image: initial; + border-radius: 4px; + margin: auto; + margin-bottom: 10px; + + &:not(:disabled):hover { + cursor: pointer; + opacity: 0.8; + } + + &.darker { + background-color: #d7d7d7; + color: #000; + } + + .subtext { + font-size: 12px; + } + } +` + +export const ModalFlex = styled.div` + width: 100%; + display: flex; + flex-wrap: no-wrap; + justify-content: space-between; + align-items: top; + + div { + flex: 1 1 0; + } + + img { + max-width: 100%; + width: auto; + height: 30vh; + display: block; + margin: auto; + } + + .center { + text-align: center; + } +` diff --git a/src/components/Modals/index.tsx b/src/components/Modals/index.tsx index 78caa4649f..285ba08742 100644 --- a/src/components/Modals/index.tsx +++ b/src/components/Modals/index.tsx @@ -8,6 +8,8 @@ import { } from './styled' import Icon from '../atoms/Icon' import { mdiChevronRightCircleOutline } from '@mdi/js' +import { usePreferences } from '../../lib/preferences' +import DownloadOurAppModal from './contents/DownloadOurAppModal' interface ModalsRenderingOptions { closable: boolean @@ -17,36 +19,41 @@ interface ModalsRenderingOptions { export default () => { const { modalsContent, closeModals } = useModals() - - if (modalsContent == null) return null + const { setPreferences } = usePreferences() const content = useMemo((): ModalsRenderingOptions => { - let basicModal: ModalsRenderingOptions = { + const basicModal: ModalsRenderingOptions = { closable: true, body: <> } switch (modalsContent) { case 'download-app': - basicModal.body = hey + basicModal.body = + basicModal.onSkip = () => { + setPreferences({ + 'general.enableDownloadAppModal': false + }) + closeModals() + } break default: break } return basicModal - }, [modalsContent]) + }, [modalsContent, setPreferences, closeModals]) const closeHandler = useCallback(() => { if (content.onSkip != null) { return content.onSkip() } return closeModals() - }, [content]) + }, [closeModals, content]) const keydownHandler = useMemo(() => { return (event: KeyboardEvent) => { - if (!closed && event.key === 'Escape' && content.closable) { + if (event.key === 'Escape') { closeHandler() } } @@ -54,23 +61,30 @@ export default () => { useGlobalKeyDownHandler(keydownHandler) const backgroundClickHandler = useMemo(() => { - if (!content.closable) { - return null + return (event: MouseEvent) => { + event.preventDefault() + closeHandler() } - return closeHandler() }, [closeHandler]) + if (modalsContent == null) return null + return ( - + <> + {content.body} {content.closable && ( - Skip + + Skip + )} - + ) } diff --git a/src/components/Modals/styled.ts b/src/components/Modals/styled.ts index 62e3637558..9bba07db77 100644 --- a/src/components/Modals/styled.ts +++ b/src/components/Modals/styled.ts @@ -30,7 +30,7 @@ export const StyledModalsContainer = styled.div` bottom: 0; margin: auto; width: 50vw; - height: 60vh; + height: 70vh; ${border} ${backgroundColor} ${contextMenuShadow} @@ -47,8 +47,8 @@ export const StyledModalsHeader = styled.h1` export const StyledModalsSkipButton = styled.button` position: absolute; bottom: 0; - right: 30px; - width: 40px; + right: 2%; + width: auto; height: 40px; background-color: transparent; border: none; @@ -57,8 +57,12 @@ export const StyledModalsSkipButton = styled.button` cursor: pointer; ${iconColor} + span { + line-height: 20px; + vertical-align: middle; + } + .icon { - display: inline-block; vertical-align: middle; } ` diff --git a/src/components/Router.tsx b/src/components/Router.tsx index af8bb88cfd..d172c3774b 100644 --- a/src/components/Router.tsx +++ b/src/components/Router.tsx @@ -7,11 +7,14 @@ import { useDb } from '../lib/db' import AttachmentsPage from './AttachmentsPage/AttachmentsPage' import TutorialsPage from './Tutorials/TutorialsPage' import useRedirectHandler from '../lib/router/redirect' +import useLoadModalsOnRouteChangeHandler from '../lib/modals/loadModalsOnRouteChange' export default () => { const routeParams = useRouteParams() const db = useDb() + useRedirectHandler() + useLoadModalsOnRouteChangeHandler() switch (routeParams.name) { case 'storages.allNotes': diff --git a/src/index.tsx b/src/index.tsx index 1a9d3d5c71..485c12527a 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,22 +4,22 @@ import App from './components/App' import { RouterProvider } from './lib/router' import { ContextMenuProvider } from './lib/contextMenu' import { DialogProvider } from './lib/dialog' +import { ModalsProvider } from './lib/modals' import { combineProviders } from './lib/utils/context' import { DbProvider } from './lib/db' import { PreferencesProvider } from './lib/preferences' import { GeneralStatusProvider } from './lib/generalStatus' import { PreviewStyleProvider } from './lib/preview' -import { ModalsProvider } from './lib/modals' const CombinedProvider = combineProviders( PreviewStyleProvider, GeneralStatusProvider, PreferencesProvider, + ModalsProvider, DialogProvider, ContextMenuProvider, DbProvider, - RouterProvider, - ModalsProvider + RouterProvider ) function render(Component: typeof App) { diff --git a/src/lib/modals/index.tsx b/src/lib/modals/index.tsx index d713e08ccc..f6b9478a03 100644 --- a/src/lib/modals/index.tsx +++ b/src/lib/modals/index.tsx @@ -1,2 +1,3 @@ export * from './types' export * from './store' +export * from './loadModalsOnRouteChange' diff --git a/src/lib/modals/loadModals.ts b/src/lib/modals/loadModals.ts deleted file mode 100644 index 6db47af9b5..0000000000 --- a/src/lib/modals/loadModals.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { useDb } from '../db' -import { useRouter } from '../router/store' -import { useEffect } from 'react' -import { useModals } from './store' - -export default function useLoadModalsHandler() { - const db = useDb() - const { pathname } = useRouter() - const { setModalsContent } = useModals() - - useEffect(() => { - if (!db.initialized || db.storageMap == null) { - return - } - if ( - pathname === '/app/storages' && - Object.keys(db.storageMap).length === 0 - ) { - setModalsContent('download-app') - } - return - }, [pathname, db.initialized]) -} diff --git a/src/lib/modals/loadModalsOnRouteChange.ts b/src/lib/modals/loadModalsOnRouteChange.ts new file mode 100644 index 0000000000..bd23bbf3e0 --- /dev/null +++ b/src/lib/modals/loadModalsOnRouteChange.ts @@ -0,0 +1,23 @@ +import { useDb } from '../db' +import { useRouter } from '../router/store' +import { useEffect, useRef } from 'react' +import { useModals } from './store' +import { usePreferences } from '../preferences' + +export default function useLoadModalsOnRouteChangeHandler() { + const { pathname } = useRouter() + const db = useDb() + const { openModals } = useModals() + const { preferences } = usePreferences() + + const storageMapRef = useRef(db.storageMap) + useEffect(() => { + if ( + pathname === '/app/storages' && + Object.keys(storageMapRef.current).length === 0 && + preferences['general.enableDownloadAppModal'] === true + ) { + openModals('download-app') + } + }, [pathname, openModals, preferences]) +} diff --git a/src/lib/modals/store.ts b/src/lib/modals/store.ts index 1c3d7916bf..bbdad10f0e 100644 --- a/src/lib/modals/store.ts +++ b/src/lib/modals/store.ts @@ -1,6 +1,6 @@ +import { createStoreContext } from '../utils/context' import { useState, useCallback } from 'react' import { ModalsContentOptions, ModalsContext } from './types' -import { createStoreContext } from '../utils/context' export * from './types' function useModalsStore(): ModalsContext { @@ -9,6 +9,10 @@ function useModalsStore(): ModalsContext { setModalsContent ] = useState(null) + const openModals = useCallback((content: ModalsContentOptions) => { + setModalsContent(content) + }, []) + const closeModals = useCallback(() => { setModalsContent(null) }, []) @@ -16,7 +20,7 @@ function useModalsStore(): ModalsContext { return { modalsContent, closeModals, - setModalsContent + openModals } } diff --git a/src/lib/modals/types.ts b/src/lib/modals/types.ts index 0ceaddee8f..9030305ecc 100644 --- a/src/lib/modals/types.ts +++ b/src/lib/modals/types.ts @@ -9,6 +9,6 @@ export interface ModalsRenderingOptions { export interface ModalsContext { modalsContent: ModalsContentOptions | null - setModalsContent(options: ModalsContentOptions): void - closeModals(): void + openModals: (options: ModalsContentOptions) => void + closeModals: () => void } diff --git a/src/lib/preferences/store.ts b/src/lib/preferences/store.ts index 463a8de626..99295f36d4 100644 --- a/src/lib/preferences/store.ts +++ b/src/lib/preferences/store.ts @@ -30,6 +30,7 @@ const basePreferences: Preferences = { 'general.theme': 'dark', 'general.noteSorting': 'date-updated', 'general.enableAnalytics': true, + 'general.enableDownloadAppModal': true, 'general.tutorials': 'display', // Editor diff --git a/src/lib/preferences/types.ts b/src/lib/preferences/types.ts index ab6a660eb1..156b2db66c 100644 --- a/src/lib/preferences/types.ts +++ b/src/lib/preferences/types.ts @@ -19,6 +19,7 @@ export interface Preferences { 'general.theme': GeneralThemeOptions 'general.noteSorting': GeneralNoteSortingOptions 'general.enableAnalytics': boolean + 'general.enableDownloadAppModal': boolean 'general.tutorials': GeneralTutorialsOptions // Editor diff --git a/src/lib/router/redirect.ts b/src/lib/router/redirect.ts index 94f345793c..dd51d40357 100644 --- a/src/lib/router/redirect.ts +++ b/src/lib/router/redirect.ts @@ -7,12 +7,8 @@ export default function useRedirectHandler() { const { push, pathname } = useRouter() useEffect(() => { - if (!db.initialized || db.storageMap == null) { - return - } if (pathname === '/app' && Object.keys(db.storageMap).length === 0) { push('/app/storages') } - return - }, [pathname, db.initialized]) + }, [pathname, db.storageMap, push]) } diff --git a/src/lib/router/utils.ts b/src/lib/router/utils.ts index 1c785555aa..d7b51375d6 100644 --- a/src/lib/router/utils.ts +++ b/src/lib/router/utils.ts @@ -215,7 +215,7 @@ export const usePathnameWithoutNoteId = () => { }, [routeParams, pathname]) } -export const currentTutorialPathname = () => { +export const useCurrentTutorialPathname = () => { const routeParams = useRouteParams() return useMemo(() => { switch (routeParams.name) { From 1568b487c172dce08b591bae8a135bd18952ac32 Mon Sep 17 00:00:00 2001 From: davy-c Date: Thu, 12 Dec 2019 15:48:17 +0900 Subject: [PATCH 10/14] redirect to first storage on /app --- src/lib/router/redirect.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/lib/router/redirect.ts b/src/lib/router/redirect.ts index dd51d40357..0432327653 100644 --- a/src/lib/router/redirect.ts +++ b/src/lib/router/redirect.ts @@ -1,14 +1,22 @@ import { useDb } from '../db' import { useRouter } from './store' -import { useEffect } from 'react' +import { useEffect, useMemo } from 'react' +import { entries } from '../db/utils' export default function useRedirectHandler() { const db = useDb() const { push, pathname } = useRouter() + const storageEntries = useMemo(() => { + return entries(db.storageMap) + }, [db.storageMap]) + useEffect(() => { - if (pathname === '/app' && Object.keys(db.storageMap).length === 0) { - push('/app/storages') - } + if (pathname === '/app') + if (storageEntries.length === 0) { + push('/app/storages') + } else { + push(`/app/storages/${storageEntries[0][1].id}`) + } }, [pathname, db.storageMap, push]) } From ab3f3796e67a37434f192eaadd14476fd201c605 Mon Sep 17 00:00:00 2001 From: davy-c Date: Thu, 12 Dec 2019 15:50:01 +0900 Subject: [PATCH 11/14] fix component singular name --- src/components/App.tsx | 4 ++-- .../{Modals => Modal}/contents/DownloadOurAppModal.tsx | 0 src/components/{Modals => Modal}/contents/styled.ts | 0 src/components/{Modals => Modal}/index.tsx | 0 src/components/{Modals => Modal}/styled.ts | 0 5 files changed, 2 insertions(+), 2 deletions(-) rename src/components/{Modals => Modal}/contents/DownloadOurAppModal.tsx (100%) rename src/components/{Modals => Modal}/contents/styled.ts (100%) rename src/components/{Modals => Modal}/index.tsx (100%) rename src/components/{Modals => Modal}/styled.ts (100%) diff --git a/src/components/App.tsx b/src/components/App.tsx index ff998975a8..5aedd5fd21 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -16,7 +16,7 @@ import '../lib/i18n' import '../lib/analytics' import CodeMirrorStyle from './CodeMirrorStyle' import { useGeneralStatus } from '../lib/generalStatus' -import Modals from './Modals' +import Modal from './Modal' const App = () => { const { initialize, initialized } = useDb() @@ -68,7 +68,7 @@ const App = () => { - +
diff --git a/src/components/Modals/contents/DownloadOurAppModal.tsx b/src/components/Modal/contents/DownloadOurAppModal.tsx similarity index 100% rename from src/components/Modals/contents/DownloadOurAppModal.tsx rename to src/components/Modal/contents/DownloadOurAppModal.tsx diff --git a/src/components/Modals/contents/styled.ts b/src/components/Modal/contents/styled.ts similarity index 100% rename from src/components/Modals/contents/styled.ts rename to src/components/Modal/contents/styled.ts diff --git a/src/components/Modals/index.tsx b/src/components/Modal/index.tsx similarity index 100% rename from src/components/Modals/index.tsx rename to src/components/Modal/index.tsx diff --git a/src/components/Modals/styled.ts b/src/components/Modal/styled.ts similarity index 100% rename from src/components/Modals/styled.ts rename to src/components/Modal/styled.ts From 3154a75bfe0bf56755c20bf1e29ce920a55667df Mon Sep 17 00:00:00 2001 From: davy-c Date: Thu, 12 Dec 2019 15:52:15 +0900 Subject: [PATCH 12/14] change modal store to singular name --- src/components/Modal/index.tsx | 16 +++++----- src/components/Router.tsx | 2 +- src/index.tsx | 4 +-- src/lib/{modals => modal}/index.tsx | 0 .../loadModalsOnRouteChange.ts | 8 ++--- src/lib/modal/store.ts | 29 ++++++++++++++++++ src/lib/{modals => modal}/types.ts | 6 ++-- src/lib/modals/store.ts | 30 ------------------- 8 files changed, 47 insertions(+), 48 deletions(-) rename src/lib/{modals => modal}/index.tsx (100%) rename src/lib/{modals => modal}/loadModalsOnRouteChange.ts (79%) create mode 100644 src/lib/modal/store.ts rename src/lib/{modals => modal}/types.ts (62%) delete mode 100644 src/lib/modals/store.ts diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index 285ba08742..f75822a21e 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -1,6 +1,6 @@ import React, { useMemo, useCallback } from 'react' import { useGlobalKeyDownHandler } from '../../lib/keyboard' -import { useModals } from '../../lib/modals/store' +import { useModal } from '../../lib/modal/store' import { StyledModalsBackground, StyledModalsContainer, @@ -18,7 +18,7 @@ interface ModalsRenderingOptions { } export default () => { - const { modalsContent, closeModals } = useModals() + const { modalContent, closeModal } = useModal() const { setPreferences } = usePreferences() const content = useMemo((): ModalsRenderingOptions => { @@ -27,14 +27,14 @@ export default () => { body: <> } - switch (modalsContent) { + switch (modalContent) { case 'download-app': basicModal.body = basicModal.onSkip = () => { setPreferences({ 'general.enableDownloadAppModal': false }) - closeModals() + closeModal() } break default: @@ -42,14 +42,14 @@ export default () => { } return basicModal - }, [modalsContent, setPreferences, closeModals]) + }, [modalContent, setPreferences, closeModal]) const closeHandler = useCallback(() => { if (content.onSkip != null) { return content.onSkip() } - return closeModals() - }, [closeModals, content]) + return closeModal() + }, [closeModal, content]) const keydownHandler = useMemo(() => { return (event: KeyboardEvent) => { @@ -67,7 +67,7 @@ export default () => { } }, [closeHandler]) - if (modalsContent == null) return null + if (modalContent == null) return null return ( <> diff --git a/src/components/Router.tsx b/src/components/Router.tsx index d172c3774b..664ab4b33a 100644 --- a/src/components/Router.tsx +++ b/src/components/Router.tsx @@ -7,7 +7,7 @@ import { useDb } from '../lib/db' import AttachmentsPage from './AttachmentsPage/AttachmentsPage' import TutorialsPage from './Tutorials/TutorialsPage' import useRedirectHandler from '../lib/router/redirect' -import useLoadModalsOnRouteChangeHandler from '../lib/modals/loadModalsOnRouteChange' +import useLoadModalsOnRouteChangeHandler from '../lib/modal/loadModalsOnRouteChange' export default () => { const routeParams = useRouteParams() diff --git a/src/index.tsx b/src/index.tsx index 485c12527a..462f919e2e 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,7 +4,7 @@ import App from './components/App' import { RouterProvider } from './lib/router' import { ContextMenuProvider } from './lib/contextMenu' import { DialogProvider } from './lib/dialog' -import { ModalsProvider } from './lib/modals' +import { ModalProvider } from './lib/modal' import { combineProviders } from './lib/utils/context' import { DbProvider } from './lib/db' import { PreferencesProvider } from './lib/preferences' @@ -15,7 +15,7 @@ const CombinedProvider = combineProviders( PreviewStyleProvider, GeneralStatusProvider, PreferencesProvider, - ModalsProvider, + ModalProvider, DialogProvider, ContextMenuProvider, DbProvider, diff --git a/src/lib/modals/index.tsx b/src/lib/modal/index.tsx similarity index 100% rename from src/lib/modals/index.tsx rename to src/lib/modal/index.tsx diff --git a/src/lib/modals/loadModalsOnRouteChange.ts b/src/lib/modal/loadModalsOnRouteChange.ts similarity index 79% rename from src/lib/modals/loadModalsOnRouteChange.ts rename to src/lib/modal/loadModalsOnRouteChange.ts index bd23bbf3e0..cb4bd3dd7d 100644 --- a/src/lib/modals/loadModalsOnRouteChange.ts +++ b/src/lib/modal/loadModalsOnRouteChange.ts @@ -1,13 +1,13 @@ import { useDb } from '../db' import { useRouter } from '../router/store' import { useEffect, useRef } from 'react' -import { useModals } from './store' +import { useModal } from './store' import { usePreferences } from '../preferences' export default function useLoadModalsOnRouteChangeHandler() { const { pathname } = useRouter() const db = useDb() - const { openModals } = useModals() + const { openModal } = useModal() const { preferences } = usePreferences() const storageMapRef = useRef(db.storageMap) @@ -17,7 +17,7 @@ export default function useLoadModalsOnRouteChangeHandler() { Object.keys(storageMapRef.current).length === 0 && preferences['general.enableDownloadAppModal'] === true ) { - openModals('download-app') + openModal('download-app') } - }, [pathname, openModals, preferences]) + }, [pathname, openModal, preferences]) } diff --git a/src/lib/modal/store.ts b/src/lib/modal/store.ts new file mode 100644 index 0000000000..a0ffa6b7b7 --- /dev/null +++ b/src/lib/modal/store.ts @@ -0,0 +1,29 @@ +import { createStoreContext } from '../utils/context' +import { useState, useCallback } from 'react' +import { ModalsContentOptions, ModalsContext } from './types' +export * from './types' + +function useModalStore(): ModalsContext { + const [modalContent, setModalContent] = useState( + null + ) + + const openModal = useCallback((content: ModalsContentOptions) => { + setModalContent(content) + }, []) + + const closeModal = useCallback(() => { + setModalContent(null) + }, []) + + return { + modalContent, + closeModal, + openModal + } +} + +export const { + StoreProvider: ModalProvider, + useStore: useModal +} = createStoreContext(useModalStore, 'modal') diff --git a/src/lib/modals/types.ts b/src/lib/modal/types.ts similarity index 62% rename from src/lib/modals/types.ts rename to src/lib/modal/types.ts index 9030305ecc..2f74b279ca 100644 --- a/src/lib/modals/types.ts +++ b/src/lib/modal/types.ts @@ -8,7 +8,7 @@ export interface ModalsRenderingOptions { } export interface ModalsContext { - modalsContent: ModalsContentOptions | null - openModals: (options: ModalsContentOptions) => void - closeModals: () => void + modalContent: ModalsContentOptions | null + openModal: (options: ModalsContentOptions) => void + closeModal: () => void } diff --git a/src/lib/modals/store.ts b/src/lib/modals/store.ts deleted file mode 100644 index bbdad10f0e..0000000000 --- a/src/lib/modals/store.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { createStoreContext } from '../utils/context' -import { useState, useCallback } from 'react' -import { ModalsContentOptions, ModalsContext } from './types' -export * from './types' - -function useModalsStore(): ModalsContext { - const [ - modalsContent, - setModalsContent - ] = useState(null) - - const openModals = useCallback((content: ModalsContentOptions) => { - setModalsContent(content) - }, []) - - const closeModals = useCallback(() => { - setModalsContent(null) - }, []) - - return { - modalsContent, - closeModals, - openModals - } -} - -export const { - StoreProvider: ModalsProvider, - useStore: useModals -} = createStoreContext(useModalsStore, 'modals') From 695a032054a4bfdfe5aaad7b52d68cff06e427e7 Mon Sep 17 00:00:00 2001 From: davy-c Date: Thu, 12 Dec 2019 16:09:42 +0900 Subject: [PATCH 13/14] changes to redirect controller --- src/components/Router.tsx | 2 -- src/lib/modal/index.tsx | 1 - src/lib/modal/loadModalsOnRouteChange.ts | 23 ------------------- src/lib/router/redirect.ts | 29 +++++++++++++++--------- 4 files changed, 18 insertions(+), 37 deletions(-) delete mode 100644 src/lib/modal/loadModalsOnRouteChange.ts diff --git a/src/components/Router.tsx b/src/components/Router.tsx index 664ab4b33a..374f622076 100644 --- a/src/components/Router.tsx +++ b/src/components/Router.tsx @@ -7,14 +7,12 @@ import { useDb } from '../lib/db' import AttachmentsPage from './AttachmentsPage/AttachmentsPage' import TutorialsPage from './Tutorials/TutorialsPage' import useRedirectHandler from '../lib/router/redirect' -import useLoadModalsOnRouteChangeHandler from '../lib/modal/loadModalsOnRouteChange' export default () => { const routeParams = useRouteParams() const db = useDb() useRedirectHandler() - useLoadModalsOnRouteChangeHandler() switch (routeParams.name) { case 'storages.allNotes': diff --git a/src/lib/modal/index.tsx b/src/lib/modal/index.tsx index f6b9478a03..d713e08ccc 100644 --- a/src/lib/modal/index.tsx +++ b/src/lib/modal/index.tsx @@ -1,3 +1,2 @@ export * from './types' export * from './store' -export * from './loadModalsOnRouteChange' diff --git a/src/lib/modal/loadModalsOnRouteChange.ts b/src/lib/modal/loadModalsOnRouteChange.ts deleted file mode 100644 index cb4bd3dd7d..0000000000 --- a/src/lib/modal/loadModalsOnRouteChange.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { useDb } from '../db' -import { useRouter } from '../router/store' -import { useEffect, useRef } from 'react' -import { useModal } from './store' -import { usePreferences } from '../preferences' - -export default function useLoadModalsOnRouteChangeHandler() { - const { pathname } = useRouter() - const db = useDb() - const { openModal } = useModal() - const { preferences } = usePreferences() - - const storageMapRef = useRef(db.storageMap) - useEffect(() => { - if ( - pathname === '/app/storages' && - Object.keys(storageMapRef.current).length === 0 && - preferences['general.enableDownloadAppModal'] === true - ) { - openModal('download-app') - } - }, [pathname, openModal, preferences]) -} diff --git a/src/lib/router/redirect.ts b/src/lib/router/redirect.ts index 0432327653..1a71669c05 100644 --- a/src/lib/router/redirect.ts +++ b/src/lib/router/redirect.ts @@ -1,22 +1,29 @@ import { useDb } from '../db' import { useRouter } from './store' -import { useEffect, useMemo } from 'react' +import { useEffect, useRef } from 'react' import { entries } from '../db/utils' +import { useModal } from '../modal' +import { usePreferences } from '../preferences' export default function useRedirectHandler() { const db = useDb() const { push, pathname } = useRouter() + const { openModal } = useModal() + const { preferences } = usePreferences() - const storageEntries = useMemo(() => { - return entries(db.storageMap) - }, [db.storageMap]) - + const storageMapRef = useRef(db.storageMap) useEffect(() => { - if (pathname === '/app') - if (storageEntries.length === 0) { - push('/app/storages') - } else { - push(`/app/storages/${storageEntries[0][1].id}`) + const storageEntries = entries(storageMapRef.current) + + if (pathname !== '/app') return + + if (storageEntries.length === 0) { + if (preferences['general.enableDownloadAppModal'] === true) { + openModal('download-app') } - }, [pathname, db.storageMap, push]) + push('/app/storages') + } else { + push(`/app/storages/${storageEntries[0][1].id}`) + } + }, [pathname, push]) } From 6162f6af89792389dca549859acadcf68dc8b044 Mon Sep 17 00:00:00 2001 From: davy-c Date: Thu, 12 Dec 2019 16:11:48 +0900 Subject: [PATCH 14/14] replace instead of push --- src/lib/router/redirect.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib/router/redirect.ts b/src/lib/router/redirect.ts index 1a71669c05..d6d69c32a9 100644 --- a/src/lib/router/redirect.ts +++ b/src/lib/router/redirect.ts @@ -7,7 +7,7 @@ import { usePreferences } from '../preferences' export default function useRedirectHandler() { const db = useDb() - const { push, pathname } = useRouter() + const { replace, pathname } = useRouter() const { openModal } = useModal() const { preferences } = usePreferences() @@ -18,12 +18,12 @@ export default function useRedirectHandler() { if (pathname !== '/app') return if (storageEntries.length === 0) { - if (preferences['general.enableDownloadAppModal'] === true) { + if (preferences['general.enableDownloadAppModal']) { openModal('download-app') } - push('/app/storages') + replace('/app/storages') } else { - push(`/app/storages/${storageEntries[0][1].id}`) + replace(`/app/storages/${storageEntries[0][1].id}`) } - }, [pathname, push]) + }, [pathname, replace]) }