From 23281ed84e9e5ce2aa5ee84afd223df5cd430066 Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Wed, 15 Apr 2020 14:50:14 +0900 Subject: [PATCH 01/53] Improve empty note list style --- src/components/organisms/NoteList/NoteList.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/organisms/NoteList/NoteList.tsx b/src/components/organisms/NoteList/NoteList.tsx index b0899b5f04..2e83346658 100644 --- a/src/components/organisms/NoteList/NoteList.tsx +++ b/src/components/organisms/NoteList/NoteList.tsx @@ -8,6 +8,7 @@ import { iconColor, noteListIconColor, selectTabStyle, + disabledUiTextColor, } from '../../../lib/styled/styleFunctions' import { IconEdit, IconLoupe, IconArrowSingleDown } from '../../icons' import { useTranslation } from 'react-i18next' @@ -85,17 +86,16 @@ export const StyledNoteListContainer = styled.div` select { -webkit-appearance: none; -moz-appearance: none; - appearance: none; + border: none; + background: transparent; } + ${borderBottom}; + ${noteListIconColor}; } - - .newNoteButton { - width: 35px; - height: 30px; - font-size: 24px; - background: transparent; - border: none; - ${noteListIconColor} + .empty { + user-select: none; + padding: 10px; + ${disabledUiTextColor}; } ` From f319cbae54132868bbf19a6dc402492eef78b90a Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Wed, 15 Apr 2020 16:51:14 +0900 Subject: [PATCH 02/53] Discard StorageAllNotes route completely --- src/components/Router.tsx | 1 - .../SideNavigator/SideNavigator.tsx | 9 ------- src/components/pages/NotePage.tsx | 27 ++----------------- src/lib/router/types.ts | 7 ----- 4 files changed, 2 insertions(+), 42 deletions(-) diff --git a/src/components/Router.tsx b/src/components/Router.tsx index 5b13d96a55..74ac126c61 100644 --- a/src/components/Router.tsx +++ b/src/components/Router.tsx @@ -20,7 +20,6 @@ export default () => { useRedirectHandler() switch (routeParams.name) { - case 'storages.allNotes': case 'storages.bookmarks': case 'storages.notes': case 'storages.trashCan': diff --git a/src/components/SideNavigator/SideNavigator.tsx b/src/components/SideNavigator/SideNavigator.tsx index b7c9dda073..0121dba9d1 100644 --- a/src/components/SideNavigator/SideNavigator.tsx +++ b/src/components/SideNavigator/SideNavigator.tsx @@ -185,15 +185,6 @@ export default () => { - {/* - } - depth={0} - className='allnotes-sidenav' - label='All Notes' - active={currentPathname === `/app/notes`} - onClick={() => push(`/app/notes`)} - /> */} } diff --git a/src/components/pages/NotePage.tsx b/src/components/pages/NotePage.tsx index 8f40dce961..6dcbc6fde8 100644 --- a/src/components/pages/NotePage.tsx +++ b/src/components/pages/NotePage.tsx @@ -4,7 +4,6 @@ import styled from '../../lib/styled' import NoteDetail from '../organisms/NoteDetail' import { useRouteParams, - StorageAllNotes, StorageNotesRouteParams, StorageTrashCanRouteParams, StorageTagsRouteParams, @@ -14,7 +13,7 @@ import { } from '../../lib/router' import { useDb } from '../../lib/db' import TwoPaneLayout from '../atoms/TwoPaneLayout' -import { PopulatedNoteDoc, NoteStorage, ObjectMap } from '../../lib/db/types' +import { PopulatedNoteDoc, NoteStorage } from '../../lib/db/types' import { useGeneralStatus, ViewModeType } from '../../lib/generalStatus' import { useDialog, DialogIconTypes } from '../../lib/dialog' import { escapeRegExp } from '../../lib/string' @@ -49,7 +48,6 @@ export default () => { addAttachments, } = useDb() const routeParams = useRouteParams() as - | StorageAllNotes | StorageNotesRouteParams | StorageTrashCanRouteParams | StorageTagsRouteParams @@ -72,21 +70,6 @@ export default () => { const notes = useMemo((): PopulatedNoteDoc[] => { if (currentStorage == null) { - if (routeParams.name === 'storages.allNotes') { - const allNotesMap = (Object.values(storageMap) as NoteStorage[]).reduce( - (map, storage) => { - ;(Object.values(storage.noteMap) as PopulatedNoteDoc[]).forEach( - (note) => (map[note._id] = note) - ) - return map - }, - {} as ObjectMap - ) - - return (Object.values(allNotesMap) as PopulatedNoteDoc[]).filter( - (note) => !note.trashed - ) - } if (routeParams.name === 'storages.bookmarks') { return (Object.values(storageMap) as NoteStorage[]) .map((storage) => { @@ -99,10 +82,6 @@ export default () => { return [] } switch (routeParams.name) { - case 'storages.allNotes': - return (Object.values( - currentStorage.noteMap - ) as PopulatedNoteDoc[]).filter((note) => !note.trashed) case 'storages.notes': const { folderPathname } = routeParams const folder = currentStorage.folderMap[folderPathname] @@ -216,9 +195,7 @@ export default () => { toggleViewMode, ]) - const showCreateNoteInList = - routeParams.name === 'storages.notes' || - routeParams.name === 'storages.allNotes' + const showCreateNoteInList = routeParams.name === 'storages.notes' const breadCrumbs = useMemo(() => { if (currentNote == null || currentNote.folderPathname === '/') diff --git a/src/lib/router/types.ts b/src/lib/router/types.ts index 6638e597a3..f87c29eaab 100644 --- a/src/lib/router/types.ts +++ b/src/lib/router/types.ts @@ -19,12 +19,6 @@ export interface StorageEdit extends BaseRouteParams { storageId: string } -export interface StorageAllNotes extends BaseRouteParams { - name: 'storages.allNotes' - storageId?: string - noteId?: string -} - export interface StorageBookmarkNotes extends BaseRouteParams { name: 'storages.bookmarks' storageId?: string @@ -68,7 +62,6 @@ export interface UnknownRouteparams extends BaseRouteParams { export type AllRouteParams = | StorageCreate | StorageEdit - | StorageAllNotes | StorageBookmarkNotes | StorageNotesRouteParams | StorageTrashCanRouteParams From 65bf3786cc03f4ebfcce33458c131885ae1f7d5a Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Wed, 15 Apr 2020 18:02:15 +0900 Subject: [PATCH 03/53] Improve Note listing of NotePage --- src/components/pages/NotePage.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/pages/NotePage.tsx b/src/components/pages/NotePage.tsx index 6dcbc6fde8..076cb6d6c5 100644 --- a/src/components/pages/NotePage.tsx +++ b/src/components/pages/NotePage.tsx @@ -69,8 +69,8 @@ export default () => { }, [currentPathnameWithoutNoteId]) const notes = useMemo((): PopulatedNoteDoc[] => { - if (currentStorage == null) { - if (routeParams.name === 'storages.bookmarks') { + switch (routeParams.name) { + case 'storages.bookmarks': return (Object.values(storageMap) as NoteStorage[]) .map((storage) => { return (Object.values( @@ -78,11 +78,8 @@ export default () => { ) as PopulatedNoteDoc[]).filter((note) => note.bookmarked) }) .flat() - } - return [] - } - switch (routeParams.name) { case 'storages.notes': + if (currentStorage == null) return [] const { folderPathname } = routeParams const folder = currentStorage.folderMap[folderPathname] if (folder == null) return [] @@ -94,6 +91,7 @@ export default () => { !note.trashed ) case 'storages.tags.show': + if (currentStorage == null) return [] const { tagName } = routeParams const tag = currentStorage.tagMap[tagName] if (tag == null) return [] @@ -101,11 +99,13 @@ export default () => { .map((noteId) => currentStorage.noteMap[noteId]! as PopulatedNoteDoc) .filter((note) => !note.trashed) case 'storages.trashCan': + if (currentStorage == null) return [] return (Object.values( currentStorage.noteMap ) as PopulatedNoteDoc[]).filter((note) => note.trashed) + default: + return [] } - return [] }, [storageMap, currentStorage, routeParams]) const filteredNotes = useMemo(() => { From b5028ec24a209312a82cf4174192d78fa7161364 Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Thu, 16 Apr 2020 11:40:10 +0900 Subject: [PATCH 04/53] Move NoteItem to molecuels --- .../Tutorials/TutorialsNoteItem.tsx | 2 +- .../Tutorials/TutorialsNoteList.tsx | 2 +- .../NoteList => molecules}/NoteItem.tsx | 20 +++++++++---------- .../organisms/{NoteList => }/NoteList.tsx | 16 +++++++-------- src/components/organisms/NoteList/index.ts | 3 --- 5 files changed, 20 insertions(+), 23 deletions(-) rename src/components/{organisms/NoteList => molecules}/NoteItem.tsx (92%) rename src/components/organisms/{NoteList => }/NoteList.tsx (93%) delete mode 100644 src/components/organisms/NoteList/index.ts diff --git a/src/components/Tutorials/TutorialsNoteItem.tsx b/src/components/Tutorials/TutorialsNoteItem.tsx index f58e405f9e..fc30bf701f 100644 --- a/src/components/Tutorials/TutorialsNoteItem.tsx +++ b/src/components/Tutorials/TutorialsNoteItem.tsx @@ -2,7 +2,7 @@ import React from 'react' import Link from '../atoms/Link' import cc from 'classcat' import { TutorialsNavigatorTreeItem } from '../../lib/tutorials' -import { StyledNoteListItem } from '../organisms/NoteList/NoteItem' +import { StyledNoteListItem } from '../molecules/NoteItem' type TutorialsNoteItemProps = { note: TutorialsNavigatorTreeItem diff --git a/src/components/Tutorials/TutorialsNoteList.tsx b/src/components/Tutorials/TutorialsNoteList.tsx index adcae3808f..98bf077077 100644 --- a/src/components/Tutorials/TutorialsNoteList.tsx +++ b/src/components/Tutorials/TutorialsNoteList.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useRef } from 'react' import { TutorialsNavigatorTreeItem } from '../../lib/tutorials' import TutorialsNoteItem from './TutorialsNoteItem' -import { StyledNoteListContainer } from '../organisms/NoteList/NoteList' +import { StyledNoteListContainer } from '../organisms/NoteList' import { useTranslation } from 'react-i18next' import { isWithGeneralCtrlKey, diff --git a/src/components/organisms/NoteList/NoteItem.tsx b/src/components/molecules/NoteItem.tsx similarity index 92% rename from src/components/organisms/NoteList/NoteItem.tsx rename to src/components/molecules/NoteItem.tsx index d6c5f87b7f..7af7d01717 100644 --- a/src/components/organisms/NoteList/NoteItem.tsx +++ b/src/components/molecules/NoteItem.tsx @@ -1,21 +1,21 @@ import React, { useMemo, useCallback } from 'react' -import Link from '../../atoms/Link' -import styled from '../../../lib/styled/styled' +import Link from '../atoms/Link' +import styled from '../../lib/styled/styled' import { borderBottom, uiTextColor, secondaryBackgroundColor, inputStyle, -} from '../../../lib/styled/styleFunctions' +} from '../../lib/styled/styleFunctions' import cc from 'classcat' -import { setTransferrableNoteData } from '../../../lib/dnd' -import HighlightText from '../../atoms/HighlightText' +import { setTransferrableNoteData } from '../../lib/dnd' +import HighlightText from '../atoms/HighlightText' import { formatDistanceToNow } from 'date-fns' -import { scaleAndTransformFromLeft } from '../../../lib/styled' -import { PopulatedNoteDoc } from '../../../lib/db/types' -import { useContextMenu, MenuTypes, MenuItem } from '../../../lib/contextMenu' -import { useDb } from '../../../lib/db' -import { useDialog, DialogIconTypes } from '../../../lib/dialog' +import { scaleAndTransformFromLeft } from '../../lib/styled' +import { PopulatedNoteDoc } from '../../lib/db/types' +import { useContextMenu, MenuTypes, MenuItem } from '../../lib/contextMenu' +import { useDb } from '../../lib/db' +import { useDialog, DialogIconTypes } from '../../lib/dialog' import { useTranslation } from 'react-i18next' export const StyledNoteListItem = styled.div` diff --git a/src/components/organisms/NoteList/NoteList.tsx b/src/components/organisms/NoteList.tsx similarity index 93% rename from src/components/organisms/NoteList/NoteList.tsx rename to src/components/organisms/NoteList.tsx index 2e83346658..109d1102c0 100644 --- a/src/components/organisms/NoteList/NoteList.tsx +++ b/src/components/organisms/NoteList.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useRef, ChangeEventHandler } from 'react' -import NoteItem from './NoteItem' -import { PopulatedNoteDoc } from '../../../lib/db/types' -import styled from '../../../lib/styled' +import NoteItem from '../molecules/NoteItem' +import { PopulatedNoteDoc } from '../../lib/db/types' +import styled from '../../lib/styled' import { borderBottom, inputStyle, @@ -9,15 +9,15 @@ import { noteListIconColor, selectTabStyle, disabledUiTextColor, -} from '../../../lib/styled/styleFunctions' -import { IconEdit, IconLoupe, IconArrowSingleDown } from '../../icons' +} from '../../lib/styled/styleFunctions' +import { IconEdit, IconLoupe, IconArrowSingleDown } from '../icons' import { useTranslation } from 'react-i18next' import { useGlobalKeyDownHandler, isWithGeneralCtrlKey, -} from '../../../lib/keyboard' -import { NoteListSortOptions } from '../../pages/NotePage' -import { osName } from '../../../lib/platform' +} from '../../lib/keyboard' +import { NoteListSortOptions } from '../pages/NotePage' +import { osName } from '../../lib/platform' export const StyledNoteListContainer = styled.div` display: flex; diff --git a/src/components/organisms/NoteList/index.ts b/src/components/organisms/NoteList/index.ts deleted file mode 100644 index edab82becb..0000000000 --- a/src/components/organisms/NoteList/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import NoteList from './NoteList' - -export default NoteList From a863e498462f1c2522024b578af11e01fe60d62c Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Thu, 16 Apr 2020 17:29:44 +0900 Subject: [PATCH 05/53] Improve routing for storages.notes --- src/lib/router/utils.ts | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/src/lib/router/utils.ts b/src/lib/router/utils.ts index 0e5bc340cc..d876b6ac7d 100644 --- a/src/lib/router/utils.ts +++ b/src/lib/router/utils.ts @@ -44,17 +44,6 @@ export const useRouteParams = () => { const names = pathname.slice('/app'.length).split('/').slice(1) let noteId: string | undefined = undefined - if (names[0] === 'notes') { - if (/^note:/.test(names[1])) { - noteId = names[1] - } - - return { - name: 'storages.allNotes', - noteId, - } - } - if (names[0] === 'bookmarks') { return { name: 'storages.bookmarks', @@ -92,34 +81,32 @@ export const useRouteParams = () => { const restNames = names.slice(3) if (restNames[0] == null || restNames[0] === '') { return { - name: 'storages.allNotes', + name: 'storages.notes', storageId, + folderPathname: '/', } } const folderNames = [] for (const index in restNames) { const name = restNames[index] + if (name === '') { + break + } + if (/^note:/.test(name)) { noteId = name break - } else { - folderNames.push(name) } - } - if (restNames[0].match(new RegExp(`(^note\:[A-z0-9]*)`, 'g'))) { - return { - name: 'storages.allNotes', - storageId, - noteId, - } + folderNames.push(name) } return { name: 'storages.notes', storageId, - folderPathname: '/' + folderNames.join('/'), + folderPathname: + folderNames.length === 0 ? '/' : '/' + folderNames.join('/'), noteId, } } @@ -159,11 +146,6 @@ export const usePathnameWithoutNoteId = () => { const routeParams = useRouteParams() return useMemo(() => { switch (routeParams.name) { - case 'storages.allNotes': - if (routeParams.storageId == null) { - return `/app/notes` - } - return `/app/storages/${routeParams.storageId}/notes` case 'storages.notes': return `/app/storages/${routeParams.storageId}/notes${ routeParams.folderPathname === '/' ? '' : routeParams.folderPathname From b4d243760d0b5b75978a0046deba4c3ec58b8e2e Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Thu, 16 Apr 2020 17:41:09 +0900 Subject: [PATCH 06/53] Move SideNavigator --- src/components/App.tsx | 2 +- src/components/SideNavigator/index.ts | 3 --- .../SideNavigator.tsx | 22 +++++++++---------- 3 files changed, 12 insertions(+), 15 deletions(-) delete mode 100644 src/components/SideNavigator/index.ts rename src/components/{SideNavigator => organisms}/SideNavigator.tsx (96%) diff --git a/src/components/App.tsx b/src/components/App.tsx index e42c48381e..2a01538133 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -1,5 +1,5 @@ import React, { useMemo, useCallback } from 'react' -import SideNavigator from './SideNavigator' +import SideNavigator from './organisms/SideNavigator' import Router from './Router' import GlobalStyle from './GlobalStyle' import { ThemeProvider } from 'styled-components' diff --git a/src/components/SideNavigator/index.ts b/src/components/SideNavigator/index.ts deleted file mode 100644 index 8c087c9403..0000000000 --- a/src/components/SideNavigator/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import SideNavigator from './SideNavigator' - -export default SideNavigator diff --git a/src/components/SideNavigator/SideNavigator.tsx b/src/components/organisms/SideNavigator.tsx similarity index 96% rename from src/components/SideNavigator/SideNavigator.tsx rename to src/components/organisms/SideNavigator.tsx index 0121dba9d1..ab2bb531a9 100644 --- a/src/components/SideNavigator/SideNavigator.tsx +++ b/src/components/organisms/SideNavigator.tsx @@ -8,15 +8,15 @@ import { useContextMenu, MenuTypes } from '../../lib/contextMenu' import { usePreferences } from '../../lib/preferences' import { sideBarBackgroundColor, - sideBarDefaultTextColor, + sideBarSecondaryTextColor, iconColor, sideBarTextColor, } from '../../lib/styled/styleFunctions' import SideNavigatorItem from '../molecules/SideNavigatorItem' import { useGeneralStatus } from '../../lib/generalStatus' -import ControlButton from './ControlButton' -import FolderListFragment from './FolderListFragment' -import TagListFragment from './TagListFragment' +import ControlButton from '../SideNavigator/ControlButton' +import FolderListFragment from '../SideNavigator/FolderListFragment' +import TagListFragment from '../SideNavigator/TagListFragment' import TutorialsNavigator from '../Tutorials/TutorialsNavigator' import { useUsers } from '../../lib/accounts' import { useToast } from '../../lib/toast' @@ -33,11 +33,11 @@ import { } from '../icons' import { getStorageItemId } from '../../lib/nav' -const Description = styled.nav` - margin-left: 15px; - margin-bottom: 10px; - font-size: 18px; - ${sideBarDefaultTextColor} +const SideNavigatorLabel = styled.nav` + font-size: 14px; + ${sideBarSecondaryTextColor} + user-select: none; + margin: 0.5em 1em; ` const StyledSideNavContainer = styled.nav` @@ -195,12 +195,12 @@ export default () => { onClick={() => push(`/app/bookmarks`)} /> - + Storages push('/app/storages')}> - +
{storageEntries.map(([, storage]) => { From a0879679bf2362a2683ec99bfce3ed1d74b3d5dd Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Fri, 17 Apr 2020 03:04:01 +0900 Subject: [PATCH 07/53] Extract StorageSideNavigatorItem --- .../molecules/StorageSideNavigatorItem.tsx | 246 ++++++++++++++++++ src/components/organisms/SideNavigator.tsx | 241 +---------------- 2 files changed, 253 insertions(+), 234 deletions(-) create mode 100644 src/components/molecules/StorageSideNavigatorItem.tsx diff --git a/src/components/molecules/StorageSideNavigatorItem.tsx b/src/components/molecules/StorageSideNavigatorItem.tsx new file mode 100644 index 0000000000..073add5f98 --- /dev/null +++ b/src/components/molecules/StorageSideNavigatorItem.tsx @@ -0,0 +1,246 @@ +import React from 'react' +import { getStorageItemId } from '../../lib/nav' +import { useGeneralStatus } from '../../lib/generalStatus' +import { useDialog, DialogIconTypes } from '../../lib/dialog' +import { useDb } from '../../lib/db' +import { useRouter, usePathnameWithoutNoteId } from '../../lib/router' +import { useTranslation } from 'react-i18next' +import { useToast } from '../../lib/toast' +import ControlButton from '../SideNavigator/ControlButton' +import { + IconAddRound, + IconArrowAgain, + IconSetting, + IconBook, + IconImage, + IconTrash, +} from '../icons' +import { useFirstUser } from '../../lib/preferences' +import SideNavigatorItem from './SideNavigatorItem' +import { useContextMenu, MenuTypes } from '../../lib/contextMenu' +import FolderListFragment from '../SideNavigator/FolderListFragment' +import { NoteStorage } from '../../lib/db/types' +import TagListFragment from '../SideNavigator/TagListFragment' + +interface StorageSideNavigatorItemProps { + storage: NoteStorage +} + +const StorageSideNavigatorItem = ({ + storage, +}: StorageSideNavigatorItemProps) => { + const { + toggleSideNavOpenedItem, + sideNavOpenedItemSet, + openSideNavFolderItemRecursively, + } = useGeneralStatus() + const { prompt, messageBox } = useDialog() + const { + createFolder, + renameFolder, + renameStorage, + removeStorage, + syncStorage, + } = useDb() + const { push } = useRouter() + const { t } = useTranslation() + const { pushMessage } = useToast() + const currentPathname = usePathnameWithoutNoteId() + const user = useFirstUser() + const { popup } = useContextMenu() + + const itemId = getStorageItemId(storage.id) + const storageIsFolded = !sideNavOpenedItemSet.has(itemId) + const showPromptToCreateFolder = (folderPathname: string) => { + prompt({ + title: 'Create a Folder', + message: 'Enter the path where do you want to create a folder', + iconType: DialogIconTypes.Question, + defaultValue: folderPathname === '/' ? '/' : `${folderPathname}/`, + submitButtonLabel: 'Create Folder', + onClose: async (value: string | null) => { + if (value == null) { + return + } + if (value.endsWith('/')) { + value = value.slice(0, value.length - 1) + } + await createFolder(storage.id, value) + + push(`/app/storages/${storage.id}/notes${value}`) + + // Open folder item + openSideNavFolderItemRecursively(storage.id, value) + }, + }) + } + const showPromptToRenameFolder = (folderPathname: string) => { + prompt({ + title: t('folder.rename'), + message: t('folder.renameMessage'), + iconType: DialogIconTypes.Question, + defaultValue: folderPathname.split('/').pop(), + submitButtonLabel: t('folder.rename'), + onClose: async (value: string | null) => { + const folderPathSplit = folderPathname.split('/') + if (value == null || value === '' || value === folderPathSplit.pop()) { + return + } + const newPathname = folderPathSplit.join('/') + '/' + value + try { + await renameFolder(storage.id, folderPathname, newPathname) + push(`/app/storages/${storage.id}/notes${newPathname}`) + openSideNavFolderItemRecursively(storage.id, newPathname) + } catch (error) { + pushMessage({ + title: t('general.error'), + description: t('folder.renameErrorMessage'), + }) + } + }, + }) + } + + const allNotesPagePathname = `/app/storages/${storage.id}/notes` + const allNotesPageIsActive = currentPathname === allNotesPagePathname + + const trashcanPagePathname = `/app/storages/${storage.id}/trashcan` + const trashcanPageIsActive = currentPathname === trashcanPagePathname + + const attachmentsPagePathname = `/app/storages/${storage.id}/attachments` + const attachmentsPageIsActive = currentPathname === attachmentsPagePathname + + const controlComponents = [ + showPromptToCreateFolder('/')} + icon={} + />, + ] + + if (storage.cloudStorage != null && user != null) { + const cloudSync = () => { + if (user == null) { + pushMessage({ + title: 'No User Error', + description: 'Please login first to sync the storage.', + }) + } + syncStorage(storage.id) + } + + controlComponents.unshift( + } + /> + ) + } + + controlComponents.unshift( + push(`/app/storages/${storage.id}`)} + icon={} + /> + ) + + return ( + + { + toggleSideNavOpenedItem(itemId) + }} + onClick={() => { + toggleSideNavOpenedItem(itemId) + }} + onContextMenu={(event) => { + event.preventDefault() + popup(event, [ + { + type: MenuTypes.Normal, + label: t('storage.rename'), + onClick: async () => { + prompt({ + title: `Rename "${storage.name}" storage`, + message: t('storage.renameMessage'), + iconType: DialogIconTypes.Question, + defaultValue: storage.name, + submitButtonLabel: t('storage.rename'), + onClose: async (value: string | null) => { + if (value == null) return + await renameStorage(storage.id, value) + }, + }) + }, + }, + { + type: MenuTypes.Normal, + label: t('storage.remove'), + onClick: async () => { + messageBox({ + title: `Remove "${storage.name}" storage`, + message: t('storage.removeMessage'), + iconType: DialogIconTypes.Warning, + buttons: [t('storage.remove'), t('general.cancel')], + defaultButtonIndex: 0, + cancelButtonIndex: 1, + onClose: (value: number | null) => { + if (value === 0) { + removeStorage(storage.id) + } + }, + }) + }, + }, + ]) + }} + controlComponents={controlComponents} + /> + {!storageIsFolded && ( + <> + } + active={allNotesPageIsActive} + onClick={() => push(allNotesPagePathname)} + /> + + + } + active={attachmentsPageIsActive} + onClick={() => push(attachmentsPagePathname)} + onContextMenu={(event) => { + event.preventDefault() + }} + /> + : } + active={trashcanPageIsActive} + onClick={() => push(trashcanPagePathname)} + onContextMenu={(event) => { + event.preventDefault() + // TODO: Implement context menu(restore all notes) + }} + /> + + )} + + ) +} + +export default StorageSideNavigatorItem diff --git a/src/components/organisms/SideNavigator.tsx b/src/components/organisms/SideNavigator.tsx index ab2bb531a9..58d8cd8eb3 100644 --- a/src/components/organisms/SideNavigator.tsx +++ b/src/components/organisms/SideNavigator.tsx @@ -13,25 +13,10 @@ import { sideBarTextColor, } from '../../lib/styled/styleFunctions' import SideNavigatorItem from '../molecules/SideNavigatorItem' -import { useGeneralStatus } from '../../lib/generalStatus' -import ControlButton from '../SideNavigator/ControlButton' -import FolderListFragment from '../SideNavigator/FolderListFragment' -import TagListFragment from '../SideNavigator/TagListFragment' import TutorialsNavigator from '../Tutorials/TutorialsNavigator' -import { useUsers } from '../../lib/accounts' -import { useToast } from '../../lib/toast' import { useTranslation } from 'react-i18next' -import { - IconAddRound, - IconAdjustVertical, - IconArrowAgain, - IconTrash, - IconImage, - IconSetting, - IconBook, - IconStarActive, -} from '../icons' -import { getStorageItemId } from '../../lib/nav' +import { IconAddRound, IconAdjustVertical, IconStarActive } from '../icons' +import StorageSideNavigatorItem from '../molecules/StorageSideNavigatorItem' const SideNavigatorLabel = styled.nav` font-size: 14px; @@ -121,21 +106,10 @@ const Spacer = styled.div` ` export default () => { - const { - createStorage, - createFolder, - renameFolder, - renameStorage, - removeStorage, - storageMap, - syncStorage, - } = useDb() + const { createStorage, storageMap } = useDb() const { popup } = useContextMenu() - const { prompt, messageBox } = useDialog() + const { prompt } = useDialog() const { push } = useRouter() - const [[user]] = useUsers() - const { pushMessage } = useToast() - const storageEntries = useMemo(() => { return entries(storageMap) }, [storageMap]) @@ -167,11 +141,6 @@ export default () => { ) const { toggleClosed, preferences } = usePreferences() - const { - toggleSideNavOpenedItem, - sideNavOpenedItemSet, - openSideNavFolderItemRecursively, - } = useGeneralStatus() const currentPathname = usePathnameWithoutNoteId() @@ -203,205 +172,9 @@ export default () => {
- {storageEntries.map(([, storage]) => { - const itemId = getStorageItemId(storage.id) - const storageIsFolded = !sideNavOpenedItemSet.has(itemId) - const showPromptToCreateFolder = (folderPathname: string) => { - prompt({ - title: 'Create a Folder', - message: 'Enter the path where do you want to create a folder', - iconType: DialogIconTypes.Question, - defaultValue: folderPathname === '/' ? '/' : `${folderPathname}/`, - submitButtonLabel: 'Create Folder', - onClose: async (value: string | null) => { - if (value == null) { - return - } - if (value.endsWith('/')) { - value = value.slice(0, value.length - 1) - } - await createFolder(storage.id, value) - - push(`/app/storages/${storage.id}/notes${value}`) - - // Open folder item - openSideNavFolderItemRecursively(storage.id, value) - }, - }) - } - const showPromptToRenameFolder = (folderPathname: string) => { - prompt({ - title: t('folder.rename'), - message: t('folder.renameMessage'), - iconType: DialogIconTypes.Question, - defaultValue: folderPathname.split('/').pop(), - submitButtonLabel: t('folder.rename'), - onClose: async (value: string | null) => { - const folderPathSplit = folderPathname.split('/') - if ( - value == null || - value === '' || - value === folderPathSplit.pop() - ) { - return - } - const newPathname = folderPathSplit.join('/') + '/' + value - try { - await renameFolder(storage.id, folderPathname, newPathname) - push(`/app/storages/${storage.id}/notes${newPathname}`) - openSideNavFolderItemRecursively(storage.id, newPathname) - } catch (error) { - pushMessage({ - title: t('general.error'), - description: t('folder.renameErrorMessage'), - }) - } - }, - }) - } - - const allNotesPagePathname = `/app/storages/${storage.id}/notes` - const allNotesPageIsActive = currentPathname === allNotesPagePathname - - const trashcanPagePathname = `/app/storages/${storage.id}/trashcan` - const trashcanPageIsActive = currentPathname === trashcanPagePathname - - const attachmentsPagePathname = `/app/storages/${storage.id}/attachments` - const attachmentsPageIsActive = - currentPathname === attachmentsPagePathname - - const controlComponents = [ - showPromptToCreateFolder('/')} - icon={} - />, - ] - - if (storage.cloudStorage != null && user != null) { - const cloudSync = () => { - if (user == null) { - pushMessage({ - title: 'No User Error', - description: 'Please login first to sync the storage.', - }) - } - syncStorage(storage.id) - } - - controlComponents.unshift( - } - /> - ) - } - - controlComponents.unshift( - push(`/app/storages/${storage.id}`)} - icon={} - /> - ) - - return ( - - { - toggleSideNavOpenedItem(itemId) - }} - onClick={() => { - toggleSideNavOpenedItem(itemId) - }} - onContextMenu={(event) => { - event.preventDefault() - popup(event, [ - { - type: MenuTypes.Normal, - label: t('storage.rename'), - onClick: async () => { - prompt({ - title: `Rename "${storage.name}" storage`, - message: t('storage.renameMessage'), - iconType: DialogIconTypes.Question, - defaultValue: storage.name, - submitButtonLabel: t('storage.rename'), - onClose: async (value: string | null) => { - if (value == null) return - await renameStorage(storage.id, value) - }, - }) - }, - }, - { - type: MenuTypes.Normal, - label: t('storage.remove'), - onClick: async () => { - messageBox({ - title: `Remove "${storage.name}" storage`, - message: t('storage.removeMessage'), - iconType: DialogIconTypes.Warning, - buttons: [t('storage.remove'), t('general.cancel')], - defaultButtonIndex: 0, - cancelButtonIndex: 1, - onClose: (value: number | null) => { - if (value === 0) { - removeStorage(storage.id) - } - }, - }) - }, - }, - ]) - }} - controlComponents={controlComponents} - /> - {!storageIsFolded && ( - <> - } - active={allNotesPageIsActive} - onClick={() => push(allNotesPagePathname)} - /> - - - } - active={attachmentsPageIsActive} - onClick={() => push(attachmentsPagePathname)} - onContextMenu={(event) => { - event.preventDefault() - }} - /> - : } - active={trashcanPageIsActive} - onClick={() => push(trashcanPagePathname)} - onContextMenu={(event) => { - event.preventDefault() - // TODO: Implement context menu(restore all notes) - }} - /> - - )} - - ) - })} + {storageEntries.map(([, storage]) => ( + + ))} {storageEntries.length === 0 && (
{t('storage.noStorage')}
)} From e0a28a51ccb4298785937fbce565769e458daaef Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Fri, 17 Apr 2020 03:43:25 +0900 Subject: [PATCH 08/53] Replace fold icons with mdi icons --- src/components/Modal/index.tsx | 6 ++--- src/{mobile => }/components/atoms/Icon.tsx | 0 src/components/icons/ArrowSingleDown.tsx | 27 ------------------- src/components/icons/ArrowSingleRight.tsx | 27 ------------------- src/components/icons/index.ts | 2 -- .../molecules/SideNavigatorItem.tsx | 10 ++++--- src/components/organisms/NoteList.tsx | 6 +++-- src/mobile/components/Navigator/Navigator.tsx | 2 +- src/mobile/components/atoms/TableViewCell.tsx | 2 +- .../atoms/TopBarToggleNavButton.tsx | 2 +- .../components/organisms/NoteDetail.tsx | 2 +- src/mobile/components/organisms/NoteList.tsx | 2 +- .../components/organisms/PreferencesModal.tsx | 2 +- src/mobile/components/pages/NotePage.tsx | 2 +- 14 files changed, 20 insertions(+), 72 deletions(-) rename src/{mobile => }/components/atoms/Icon.tsx (100%) delete mode 100644 src/components/icons/ArrowSingleDown.tsx delete mode 100644 src/components/icons/ArrowSingleRight.tsx diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index 902e342e20..7bccb8c6d3 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -8,8 +8,8 @@ import { } from './styled' import { usePreferences } from '../../lib/preferences' import DownloadOurAppModal from './contents/DownloadOurAppModal' -import { IconArrowSingleRight } from '../icons' - +import Icon from '../atoms/Icon' +import { mdiArrowRight } from '@mdi/js' interface ModalsRenderingOptions { closable: boolean body: JSX.Element @@ -79,7 +79,7 @@ export default () => { {content.closable && ( - Skip + Skip )} diff --git a/src/mobile/components/atoms/Icon.tsx b/src/components/atoms/Icon.tsx similarity index 100% rename from src/mobile/components/atoms/Icon.tsx rename to src/components/atoms/Icon.tsx diff --git a/src/components/icons/ArrowSingleDown.tsx b/src/components/icons/ArrowSingleDown.tsx deleted file mode 100644 index 98af130a5c..0000000000 --- a/src/components/icons/ArrowSingleDown.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { - BoostnoteIconProps, - BoostnoteIconStyledContainer, -} from '../../lib/icons' -import React from 'react' - -export const IconArrowSingleDown = (props: BoostnoteIconProps) => ( - - - - - -) diff --git a/src/components/icons/ArrowSingleRight.tsx b/src/components/icons/ArrowSingleRight.tsx deleted file mode 100644 index e3651de4c3..0000000000 --- a/src/components/icons/ArrowSingleRight.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { - BoostnoteIconProps, - BoostnoteIconStyledContainer, -} from '../../lib/icons' -import React from 'react' - -export const IconArrowSingleRight = (props: BoostnoteIconProps) => ( - - - - - -) diff --git a/src/components/icons/index.ts b/src/components/icons/index.ts index 20bc399f7e..6c65278f4f 100644 --- a/src/components/icons/index.ts +++ b/src/components/icons/index.ts @@ -5,8 +5,6 @@ export * from './Alphabet' export * from './ArrowAgain' export * from './ArrowOutput' export * from './ArrowRotate' -export * from './ArrowSingleDown' -export * from './ArrowSingleRight' export * from './Bold' export * from './Book' export * from './Check' diff --git a/src/components/molecules/SideNavigatorItem.tsx b/src/components/molecules/SideNavigatorItem.tsx index 5043bf21a3..d4fd930564 100644 --- a/src/components/molecules/SideNavigatorItem.tsx +++ b/src/components/molecules/SideNavigatorItem.tsx @@ -7,7 +7,8 @@ import { activeBackgroundColor, iconColor, } from '../../lib/styled/styleFunctions' -import { IconArrowSingleRight, IconArrowSingleDown } from '../icons' +import Icon from '../atoms/Icon' +import { mdiChevronDown, mdiChevronRight } from '@mdi/js' const Container = styled.div` position: relative; @@ -66,13 +67,14 @@ const FoldButton = styled.button` position: absolute; width: 26px; height: 26px; - padding-left: 10px; + padding-left: 0.5em; border: none; background-color: transparent; margin-right: 3px; border-radius: 2px; flex: 0 0 26px; top: 5px; + font-size: 1em; ${sideBarSecondaryTextColor} &:focus { box-shadow: none; @@ -172,9 +174,9 @@ const SideNaviagtorItem = ({ style={{ left: `${10 * depth}px` }} > {folded ? ( - + ) : ( - + )} )} diff --git a/src/components/organisms/NoteList.tsx b/src/components/organisms/NoteList.tsx index 109d1102c0..1d9706fcab 100644 --- a/src/components/organisms/NoteList.tsx +++ b/src/components/organisms/NoteList.tsx @@ -10,7 +10,7 @@ import { selectTabStyle, disabledUiTextColor, } from '../../lib/styled/styleFunctions' -import { IconEdit, IconLoupe, IconArrowSingleDown } from '../icons' +import { IconEdit, IconLoupe } from '../icons' import { useTranslation } from 'react-i18next' import { useGlobalKeyDownHandler, @@ -18,6 +18,8 @@ import { } from '../../lib/keyboard' import { NoteListSortOptions } from '../pages/NotePage' import { osName } from '../../lib/platform' +import Icon from '../atoms/Icon' +import { mdiChevronDown } from '@mdi/js' export const StyledNoteListContainer = styled.div` display: flex; @@ -207,7 +209,7 @@ const NoteList = ({ )}
- + -
-
- {viewMode === 'preview' ? ( - markdownPreviewer - ) : viewMode === 'split' ? ( - <> -
{codeEditor}
-
{markdownPreviewer}
- - ) : ( - codeEditor - )} -
- - - toggleViewMode('edit')} - icon={} - /> - toggleViewMode('split')} - icon={} - /> - toggleViewMode('preview')} - icon={} - /> - - - ) - } -} diff --git a/src/components/Tutorials/TutorialsNoteItem.tsx b/src/components/Tutorials/TutorialsNoteItem.tsx deleted file mode 100644 index fc30bf701f..0000000000 --- a/src/components/Tutorials/TutorialsNoteItem.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react' -import Link from '../atoms/Link' -import cc from 'classcat' -import { TutorialsNavigatorTreeItem } from '../../lib/tutorials' -import { StyledNoteListItem } from '../molecules/NoteItem' - -type TutorialsNoteItemProps = { - note: TutorialsNavigatorTreeItem - active: boolean - basePathname: string - focusList: () => void -} - -export default ({ - note, - active, - basePathname, - focusList, -}: TutorialsNoteItemProps) => { - const href = `${basePathname}/notes/note:${note.slug}` - - return ( - - -
-
{note.label}
-
- -
- ) -} diff --git a/src/components/Tutorials/TutorialsNoteList.tsx b/src/components/Tutorials/TutorialsNoteList.tsx deleted file mode 100644 index 98bf077077..0000000000 --- a/src/components/Tutorials/TutorialsNoteList.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import React, { useCallback, useRef } from 'react' -import { TutorialsNavigatorTreeItem } from '../../lib/tutorials' -import TutorialsNoteItem from './TutorialsNoteItem' -import { StyledNoteListContainer } from '../organisms/NoteList' -import { useTranslation } from 'react-i18next' -import { - isWithGeneralCtrlKey, - useGlobalKeyDownHandler, -} from '../../lib/keyboard' - -type TutorialsNoteListProps = { - currentTree: TutorialsNavigatorTreeItem - basePathname: string - parentTree?: TutorialsNavigatorTreeItem - selectedNote?: TutorialsNavigatorTreeItem - navigateUp: () => void - navigateDown: () => void -} - -const TutorialsNoteList = ({ - currentTree, - parentTree, - navigateUp, - navigateDown, - basePathname, - selectedNote, -}: TutorialsNoteListProps) => { - useGlobalKeyDownHandler((e) => { - switch (e.key) { - case 'j': - if (isWithGeneralCtrlKey(e)) { - e.preventDefault() - e.stopPropagation() - navigateDown() - } - break - case 'k': - if (isWithGeneralCtrlKey(e)) { - e.preventDefault() - e.stopPropagation() - navigateUp() - } - break - default: - break - } - }) - - const listRef = useRef(null) - - const focusList = useCallback(() => { - listRef.current!.focus() - }, []) - - const notes = - currentTree.type !== 'note' - ? currentTree.children.filter((child) => child.type === 'note') - : parentTree == null - ? [] - : parentTree.children.filter((child) => child.type === 'note') - - const { t } = useTranslation() - - return ( - -
    - {notes.map((note) => { - const noteIsCurrentNote = - selectedNote != null && - note.absolutePath === selectedNote.absolutePath - return ( -
  • - -
  • - ) - })} - {notes.length === 0 &&
  • {t('note.nothing')}
  • } -
-
- ) -} - -export default TutorialsNoteList diff --git a/src/components/Tutorials/TutorialsPage.tsx b/src/components/Tutorials/TutorialsPage.tsx deleted file mode 100644 index bb7bc2a97a..0000000000 --- a/src/components/Tutorials/TutorialsPage.tsx +++ /dev/null @@ -1,258 +0,0 @@ -import React, { useCallback, useMemo } from 'react' -import { tutorialsTree, TutorialsNavigatorTreeItem } from '../../lib/tutorials' -import TwoPaneLayout from '../atoms/TwoPaneLayout' -import { useGeneralStatus, ViewModeType } from '../../lib/generalStatus' -import { useRouter } from '../../lib/router' -import TutorialsNoteList from './TutorialsNoteList' -import TutorialsNoteDetail from './TutorialsNoteDetail' -import { useTranslation } from 'react-i18next' - -interface TutorialsPageProps { - pathname: string -} - -type TutoriasPagePicker = { - parentTree?: TutorialsNavigatorTreeItem - currentTree: TutorialsNavigatorTreeItem -} - -export default ({ pathname }: TutorialsPageProps) => { - const { generalStatus, setGeneralStatus } = useGeneralStatus() - const router = useRouter() - const { t } = useTranslation() - 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 - } - } - - return match - }, - [] - ) - - 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({ - noteListWidth: leftWidth, - }) - }, - [setGeneralStatus] - ) - - const toggleViewMode = useCallback( - (newMode: ViewModeType) => { - setGeneralStatus({ - noteViewMode: newMode, - }) - }, - [setGeneralStatus] - ) - - const selectedNote = useMemo((): TutorialsNavigatorTreeItem | undefined => { - if (currentTutorialBranch == null) { - return undefined - } - - if (currentTutorialBranch.currentTree.type === 'note') { - return currentTutorialBranch.currentTree - } - - const notesChildren = currentTutorialBranch.currentTree.children.filter( - (node) => node.type === 'note' - ) - if (notesChildren.length > 0) { - return notesChildren[0] - } - return undefined - }, [currentTutorialBranch]) - - const currentFolderPathname = useMemo(() => { - return pathname.split('/notes')[0] - }, [pathname]) - - const navigateUp = useCallback(() => { - if (currentTutorialBranch == null) { - return - } - - if (selectedNote == null) { - return - } - - const notes = - currentTutorialBranch.currentTree.type !== 'note' - ? currentTutorialBranch.currentTree.children.filter( - (node) => node.type === 'note' - ) - : currentTutorialBranch.parentTree != null - ? currentTutorialBranch.parentTree.children.filter( - (node) => node.type === 'note' - ) - : [] - - if (notes.length < 1) { - return - } - - let currentNoteIndex = 0 - for (let i = 0; i < notes.length; i++) { - if (selectedNote.absolutePath === notes[i].absolutePath) { - currentNoteIndex = i - break - } - } - - if (currentNoteIndex - 1 >= 0) { - router.push( - currentFolderPathname + - '/notes/note:' + - notes[currentNoteIndex - 1].slug - ) - } - return - }, [selectedNote, currentTutorialBranch, router, currentFolderPathname]) - - const navigateDown = useCallback(() => { - if (currentTutorialBranch == null) { - return - } - - if (selectedNote == null) { - return - } - - const notes = - currentTutorialBranch.currentTree.type !== 'note' - ? currentTutorialBranch.currentTree.children.filter( - (node) => node.type === 'note' - ) - : currentTutorialBranch.parentTree != null - ? currentTutorialBranch.parentTree.children.filter( - (node) => node.type === 'note' - ) - : [] - - if (notes.length < 1) { - return - } - - let currentNoteIndex = 0 - for (let i = 0; i < notes.length; i++) { - if (selectedNote.absolutePath === notes[i].absolutePath) { - currentNoteIndex = i - break - } - } - - if (currentNoteIndex + 1 >= 0 && currentNoteIndex + 1 < notes.length) { - router.push( - currentFolderPathname + - '/notes/note:' + - notes[currentNoteIndex + 1].slug - ) - } - return - }, [selectedNote, currentFolderPathname, currentTutorialBranch, router]) - - return ( - - ) - } - right={ - selectedNote == null ? ( -
{t('note.unselect')}
- ) : ( - - ) - } - onResizeEnd={updateNoteListWidth} - /> - ) -} diff --git a/src/components/organisms/Navigator.tsx b/src/components/organisms/Navigator.tsx index d3fef87f33..77e727ecb4 100644 --- a/src/components/organisms/Navigator.tsx +++ b/src/components/organisms/Navigator.tsx @@ -7,7 +7,6 @@ import { useDialog, DialogIconTypes } from '../../lib/dialog' import { useContextMenu, MenuTypes } from '../../lib/contextMenu' import { usePreferences } from '../../lib/preferences' import NavigatorItem from '../atoms/NavigatorItem' -import TutorialsNavigator from '../Tutorials/TutorialsNavigator' import { useTranslation } from 'react-i18next' import { IconAdjustVertical } from '../icons' import StorageNavigatorFragment from '../molecules/StorageNavigatorFragment' @@ -59,7 +58,7 @@ const Navigator = () => { [popup, prompt, createStorage, push] ) - const { toggleClosed, preferences } = usePreferences() + const { toggleClosed } = usePreferences() const currentPathname = usePathnameWithoutNoteId() @@ -94,7 +93,6 @@ const Navigator = () => {
{t('storage.noStorage')}
)}
- {preferences['general.tutorials'] === 'display' && } ) diff --git a/src/lib/preferences.ts b/src/lib/preferences.ts index 5a8e770e9f..5ac58abb3b 100644 --- a/src/lib/preferences.ts +++ b/src/lib/preferences.ts @@ -28,8 +28,6 @@ export type GeneralNoteSortingOptions = | 'date-updated' | 'date-created' | 'title' -export type GeneralTutorialsOptions = 'display' | 'hide' - export type EditorIndentTypeOptions = 'tab' | 'spaces' export type EditorIndentSizeOptions = 2 | 4 | 8 export type EditorKeyMapOptions = 'default' | 'vim' | 'emacs' @@ -42,7 +40,6 @@ export interface Preferences { 'general.noteSorting': GeneralNoteSortingOptions 'general.enableAnalytics': boolean 'general.enableDownloadAppModal': boolean - 'general.tutorials': GeneralTutorialsOptions 'general.enableAutoSync': boolean // Editor @@ -83,7 +80,6 @@ const basePreferences: Preferences = { 'general.noteSorting': 'date-updated', 'general.enableAnalytics': true, 'general.enableDownloadAppModal': true, - 'general.tutorials': 'display', 'general.enableAutoSync': true, // Editor diff --git a/src/lib/tutorials/files/tutorials/AboutOurCommunity.md b/src/lib/tutorials/files/tutorials/AboutOurCommunity.md deleted file mode 100644 index c7823a6faf..0000000000 --- a/src/lib/tutorials/files/tutorials/AboutOurCommunity.md +++ /dev/null @@ -1,25 +0,0 @@ -# About Our Community - -Here is some additional info on our community! We are always welcoming newcomers, so don't hesitate to say hello ;) - -## Connect with Us - -- [Slack Group](https://join.slack.com/t/boostnote-group/shared_invite/enQtMzkxOTk4ODkyNzc0LWQxZTQwNjBlMDI4YjkyYjg2MTRiZGJhNzA1YjQ5ODA5M2M0M2NlMjI5YjhiYWQzNzgzYmU0MDMwOTlmZmZmMGE) -- [Facebook Group](https://www.facebook.com/groups/boostnote/) -- [Twitter](https://twitter.com/boostnoteapp) -- [Blog](https://medium.com/boostnote) -- [Reddit](https://www.reddit.com/r/Boostnote/) - -## Supporting Boostnote - -Boostnote is an open source project. It's an independent project with its ongoing development made possible thanks to the support by our amazing backers. - -Issues on Boostnote can be funded by anyone and the money will be distributed to contributors and maintainers. If you use Boostnote please consider becoming a backer: - -[![Let's fund issues in this repository](https://issuehunt.io/static/embed/issuehunt-button-v1.svg)](https://issuehunt.io/repos/53266139) - -## More Information - -- [Website](https://boostnote.io) -- [Newsletters](https://boostnote.io/#subscribe) -- [Development Configurations](https://github.com/BoostIO/Boostnote/blob/master/docs/build.md) diff --git a/src/lib/tutorials/files/tutorials/Brainstorm.md b/src/lib/tutorials/files/tutorials/Brainstorm.md deleted file mode 100644 index ad06087f00..0000000000 --- a/src/lib/tutorials/files/tutorials/Brainstorm.md +++ /dev/null @@ -1,29 +0,0 @@ -# Template 4: Brainstorm - -## Goals/Issues - -- Point 1 -- Point 2 -- Point 3 - -## Research - -### [Boostnote](https://boostnote.io/) - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus turpis nunc, tempor et purus tempus, condimentum accumsan massa. - -## Suggestions/Ideas - -- Idea 1 -- Idea 2 -- Idea 3 - -## Final Decision - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus turpis nunc, tempor et purus tempus, condimentum accumsan massa. - -## Action Items - -- [ ] Item 1 -- [ ] Item 2 -- [ ] Item 3 diff --git a/src/lib/tutorials/files/tutorials/BugfixReport.md b/src/lib/tutorials/files/tutorials/BugfixReport.md deleted file mode 100644 index d0bc7a206c..0000000000 --- a/src/lib/tutorials/files/tutorials/BugfixReport.md +++ /dev/null @@ -1,21 +0,0 @@ -# Template 3: Bugfix Report - -## Summary of the Bug - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus turpis nunc, tempor et purus tempus, condimentum accumsan massa. - -## Why Did It Happen? - -- Lorem ipsum dolor sit amet, consectetur adipiscing elit. -- Lorem ipsum dolor sit amet, consectetur adipiscing elit. -- Lorem ipsum dolor sit amet, consectetur adipiscing elit. - -## How Did I Fix? - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus turpis nunc, tempor et purus tempus, condimentum accumsan massa. - -## How to Prevent Next Time? - -- [ ] Idea 1 -- [ ] Idea 2 -- [ ] Idea 3 diff --git a/src/lib/tutorials/files/tutorials/GetStarted.md b/src/lib/tutorials/files/tutorials/GetStarted.md deleted file mode 100644 index 319324c450..0000000000 --- a/src/lib/tutorials/files/tutorials/GetStarted.md +++ /dev/null @@ -1,118 +0,0 @@ -# Get Started - -Welcome to Boostnote :) This is a page for you to play around with. - -## 👨‍💻 Markdown Cheat Sheet 👩‍💻 - ---- - -### 1️⃣ Headings - ---- - -#### Heading 1 - -`# H1` - -#### Heading 2 - -`## H2` - -#### Heading 3 - -`### H3` - -#### Heading 4 - -`#### H4` - -#### Heading 5 - -`##### H5` - -#### Heading 6 - -`###### H6` - ---- - -### 2️⃣ Text Decoration - ---- - -#### Bold - -`**bold**` - -#### Italic - -`*italicized text*` - -#### Line Through - -`~~line through~~` - ---- - -### 3️⃣ List - ---- - -#### Ordered List - -``` -1. First Item -2. Second Item -3. Third Item -``` - -#### Unordered List - -``` -* First Item -* Second Item -* Third Item -``` - ---- - -### 4️⃣ Code Decoration - ---- - -#### Code - -`code` - -#### Code Block - -```html -Hello World! -``` - ---- - -### 5️⃣ Others - ---- - -#### Checkbox - -``` -* [x] First Item -* [ ] Second item -``` - -#### Horizontal Rule - -`---` - -#### Link - -`[Boostnote](https://boostnote.io/)` - -#### Quote - -`> This is a quote from somewhere!` - ---- diff --git a/src/lib/tutorials/files/tutorials/KeyboardShortcuts.md b/src/lib/tutorials/files/tutorials/KeyboardShortcuts.md deleted file mode 100644 index 071e7c8d18..0000000000 --- a/src/lib/tutorials/files/tutorials/KeyboardShortcuts.md +++ /dev/null @@ -1,134 +0,0 @@ -# Keyboard Shortcuts - -## Basic Shortcuts - -Here are other keyboard shortcuts which can be useful for you :) - -### Preferences - -- Open Preference - -> `Command + ,` - ---- - -- Close Preference - -> `Esc` - -### Notes - -- New Note - -> `Command + N` - ---- - -- Clone Note - -> `Command + D` - ---- - -- Next Note - -> `Command + ]` - ---- - -- Previous Note - -> `Command + [` - -### Adding Stuff - -- Add Tag - -> `Command + Shift + T` - ---- - -- Add Emoji & Symbol - -> `Command + Control + Space` - ---- - -- Generate/Update Markdown TOC - -> `Control + Shift + T` - -### Toggle Views - -- Toggle Full Screen - -> `Command + Control + F` - ---- - -- Toggle Sidebar - -> `Command + B` - ---- - -- Toggle Note Info - -> `Command + Option + I` - -### Zoom - -- Zoom In - -> `Command + =` - ---- - -- Zoom Out - -> `Command + -` - ---- - -- Actual Size - -> `Command + 0` - -### Other Useful Shortcuts - -- Focus Search - -> `Command + Shift + L` - ---- - -- Reload - -> `Command + R` - -## Hotkeys - -Hotkeys are set like below by default, but you can change them in the preference modal. - ---- - -- Show/Hide Boostnote - -> `Command + Alt + L` - ---- - -- Show/Hide Menu Bar - -> `Alt` - ---- - -- Toggle Editor Mode - -> `Command + Alt + M` - ---- - -- Delete Note - -> `Command + Shift + Delete` - ---- - -- Paste HTML - -> `Command + Shift + V` - ---- - -- Prettify Markdown - -> `Command + Shift + F` - ---- - -- Insert Current Date - -> `Command + /` - ---- - -- Insert Current Date and Time - -> `Command + Alt + /` diff --git a/src/lib/tutorials/files/tutorials/MeetingNotes.md b/src/lib/tutorials/files/tutorials/MeetingNotes.md deleted file mode 100644 index 31893a9ffe..0000000000 --- a/src/lib/tutorials/files/tutorials/MeetingNotes.md +++ /dev/null @@ -1,34 +0,0 @@ -# Template 1: Meeting Notes - -## Basic Info - -- Project Name -- Date, Time, Location -- Goal of This Meeting -- Attendees - -## Background - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus turpis nunc, tempor et purus tempus, condimentum accumsan massa. - -## Agenda - -- Topic 1 -- Topic 2 -- Topic 3 - -## Decisions - -- Decision 1 -- Decision 2 -- Decision 3 - -## Next Actions - -- [x] Task 1 -- [ ] Task 2 -- [ ] Task 3 - -## Closure - -Summary & Takeaways diff --git a/src/lib/tutorials/files/tutorials/StorageGuide.md b/src/lib/tutorials/files/tutorials/StorageGuide.md deleted file mode 100644 index dd9e832168..0000000000 --- a/src/lib/tutorials/files/tutorials/StorageGuide.md +++ /dev/null @@ -1,23 +0,0 @@ -# Storage guide - -Storages and folders can help you to organize your notes. Check this guide and start organizing to make your life easier! - -## Adding a Storage - -One of the first thing you want to do in order to use Boostnote is to create a storage. In order to do so, you can click on the link in the sidebar. - -## Storage Can Have Folders - -Each storage can have as many folders as you want, and you can create even subfolders inside there. - -You can check the Sample Storage on the sidebar and play around with it so you can get some ideas on how you want to organize with this feature! - -## Local Storage & Cloud Storage - -This feature has two storage types, local and cloud. There are no limitations for local storage number (like older version Boostnote), but if you want to create more than two cloud storage, you need to upgrade your plan to do so. [Follow this link](https://boostnote.io/) to upgrade the plan :) - -## Sync Your Cloud Storage - -The merit of cloud storage is syncing your notes on every platform. Even when you are offline, Boostnote will start syncing once it became online. - -If there is something problem and couldn't sync your notes, this app will tell you how to solve it. diff --git a/src/lib/tutorials/files/tutorials/TodaysTask.md b/src/lib/tutorials/files/tutorials/TodaysTask.md deleted file mode 100644 index dadd6ee400..0000000000 --- a/src/lib/tutorials/files/tutorials/TodaysTask.md +++ /dev/null @@ -1,14 +0,0 @@ -# Today's Task - -Let's write your today's tasks to get used to Boostnote! - -## Sample Tasks - -- [x] Download Boostnote -- [ ] Write down today's task -- [ ] Get a cup of coffee -- [ ] Turn on my favorite music - -## Write Your Own :) - -- [ ] Your first tasks is...? diff --git a/src/lib/tutorials/files/tutorials/WeeklyPlanner.md b/src/lib/tutorials/files/tutorials/WeeklyPlanner.md deleted file mode 100644 index be56d0692e..0000000000 --- a/src/lib/tutorials/files/tutorials/WeeklyPlanner.md +++ /dev/null @@ -1,55 +0,0 @@ -# Template 2: Weekly Planner - -## This Week's Goal - -- [ ] Task 1 -- [ ] Task 2 -- [ ] Task 3 - -## Monday - -- [ ] Task 1 -- [ ] Task 2 -- [ ] Task 3 - -## Tuesday - -- [ ] Task 1 -- [ ] Task 2 -- [ ] Task 3 - -## Wednesday - -- [ ] Task 1 -- [ ] Task 2 -- [ ] Task 3 - -## Thursday - -- [ ] Task 1 -- [ ] Task 2 -- [ ] Task 3 - -## Friday - -- [ ] Task 1 -- [ ] Task 2 -- [ ] Task 3 - -## Saturday - -- [ ] Task 1 -- [ ] Task 2 -- [ ] Task 3 - -## Sunday - -- [ ] Task 1 -- [ ] Task 2 -- [ ] Task 3 - -## Memo - -- I learned ... -- Memo 2 -- Memo 3 diff --git a/src/lib/tutorials/index.tsx b/src/lib/tutorials/index.tsx deleted file mode 100644 index aec59884a9..0000000000 --- a/src/lib/tutorials/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './tree' diff --git a/src/lib/tutorials/tree.ts b/src/lib/tutorials/tree.ts deleted file mode 100644 index c276b7ea3f..0000000000 --- a/src/lib/tutorials/tree.ts +++ /dev/null @@ -1,81 +0,0 @@ -export type TutorialsNavigatorTreeItem = { - label: string - slug: string - absolutePath: string - type: 'folder' | 'note' | 'storage' - children: TutorialsNavigatorTreeItem[] -} - -export const tutorialsTree: TutorialsNavigatorTreeItem[] = [ - { - label: 'Tutorials', - absolutePath: 'tutorials', - slug: 'tutorials', - type: 'storage', - 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 57751d14a9fea976bed2ce9f744d41aede9da614 Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Sun, 19 Apr 2020 11:43:58 +0900 Subject: [PATCH 28/53] Fix top control style of nav --- src/components/atoms/Spacer.tsx | 7 +++++++ src/components/organisms/Navigator.tsx | 19 +++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) create mode 100644 src/components/atoms/Spacer.tsx diff --git a/src/components/atoms/Spacer.tsx b/src/components/atoms/Spacer.tsx new file mode 100644 index 0000000000..b0a0ba8f9e --- /dev/null +++ b/src/components/atoms/Spacer.tsx @@ -0,0 +1,7 @@ +import styled from '../../lib/styled' + +const Spacer = styled.div` + flex: 1; +` + +export default Spacer diff --git a/src/components/organisms/Navigator.tsx b/src/components/organisms/Navigator.tsx index 77e727ecb4..777cb2507c 100644 --- a/src/components/organisms/Navigator.tsx +++ b/src/components/organisms/Navigator.tsx @@ -8,9 +8,10 @@ import { useContextMenu, MenuTypes } from '../../lib/contextMenu' import { usePreferences } from '../../lib/preferences' import NavigatorItem from '../atoms/NavigatorItem' import { useTranslation } from 'react-i18next' -import { IconAdjustVertical } from '../icons' import StorageNavigatorFragment from '../molecules/StorageNavigatorFragment' -import { mdiStarOutline } from '@mdi/js' +import { mdiStarOutline, mdiTuneVertical } from '@mdi/js' +import NavigatorButton from '../atoms/NavigatorButton' +import Spacer from '../atoms/Spacer' const NavigatorContainer = styled.nav` display: flex; @@ -19,8 +20,8 @@ const NavigatorContainer = styled.nav` background-color: ${({ theme }) => theme.sideNavBackgroundColor}; ` -const Spacer = styled.div` - flex: 1; +const TopControl = styled.div` + display: flex; ` const Navigator = () => { @@ -66,12 +67,10 @@ const Navigator = () => { return ( -
-
- -
+ + + + Date: Sun, 19 Apr 2020 20:38:24 +0900 Subject: [PATCH 29/53] Fix no storage message --- src/components/organisms/Navigator.tsx | 59 ++++++++++++++++---------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/src/components/organisms/Navigator.tsx b/src/components/organisms/Navigator.tsx index 777cb2507c..6f4a1d7dc7 100644 --- a/src/components/organisms/Navigator.tsx +++ b/src/components/organisms/Navigator.tsx @@ -1,17 +1,16 @@ import React, { useMemo, useCallback } from 'react' -import { useRouter, usePathnameWithoutNoteId } from '../../lib/router' +import { useRouter } from '../../lib/router' import { useDb } from '../../lib/db' import { entries } from '../../lib/db/utils' import styled from '../../lib/styled' import { useDialog, DialogIconTypes } from '../../lib/dialog' import { useContextMenu, MenuTypes } from '../../lib/contextMenu' import { usePreferences } from '../../lib/preferences' -import NavigatorItem from '../atoms/NavigatorItem' -import { useTranslation } from 'react-i18next' import StorageNavigatorFragment from '../molecules/StorageNavigatorFragment' -import { mdiStarOutline, mdiTuneVertical } from '@mdi/js' +import { mdiTuneVertical, mdiPlus } from '@mdi/js' import NavigatorButton from '../atoms/NavigatorButton' import Spacer from '../atoms/Spacer' +import { usePathnameWithoutNoteId } from '../../lib/router' const NavigatorContainer = styled.nav` display: flex; @@ -24,6 +23,27 @@ const TopControl = styled.div` display: flex; ` +const Empty = styled.button` + width: 100%; + border: none; + text-decoration: underline; + padding: 0.25em; + text-align: center; + background-color: transparent; + cursor: pointer; + + transition: color 200ms ease-in-out; + color: ${({ theme }) => theme.sideNavButtonColor}; + &:hover { + color: ${({ theme }) => theme.sideNavButtonHoverColor}; + } + + &:active, + .active { + color: ${({ theme }) => theme.sideNavButtonActiveColor}; + } +` + const Navigator = () => { const { createStorage, storageMap } = useDb() const { popup } = useContextMenu() @@ -58,38 +78,31 @@ const Navigator = () => { }, [popup, prompt, createStorage, push] ) - + const pathname = usePathnameWithoutNoteId() const { toggleClosed } = usePreferences() - const currentPathname = usePathnameWithoutNoteId() - - const { t } = useTranslation() - return ( + push('/app/storages')} + iconPath={mdiPlus} + /> - push(`/app/bookmarks`)} - /> - {/* - Storages - push('/app/storages')}> - - - */} +
{storageEntries.map(([, storage]) => ( ))} {storageEntries.length === 0 && ( -
{t('storage.noStorage')}
+ push('/app/storages')}> + There are no storages. +
+ Click here to create one. +
)}
From f123ec5092cd7550eb1efbaa2739125309cdb054 Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Sun, 19 Apr 2020 20:42:11 +0900 Subject: [PATCH 30/53] Resize Icons --- src/components/atoms/Icon.tsx | 18 +++++++++++---- src/components/atoms/NavigatorButton.tsx | 4 +++- src/components/atoms/NavigatorItem.tsx | 23 ++++++++----------- .../molecules/FolderListFragment.tsx | 4 ++-- .../molecules/StorageNavigatorFragment.tsx | 8 +++---- src/components/molecules/TagListFragment.tsx | 4 ++-- 6 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/components/atoms/Icon.tsx b/src/components/atoms/Icon.tsx index 7c891d6b9c..adda5ae2bd 100644 --- a/src/components/atoms/Icon.tsx +++ b/src/components/atoms/Icon.tsx @@ -4,15 +4,23 @@ import { Icon as MdiIcon } from '@mdi/react' interface IconProps { path: string color?: string + size?: number } -const Icon = ({ path, color = 'currentColor' }: IconProps) => ( +const Icon = ({ path, color = 'currentColor', size }: IconProps) => ( ) diff --git a/src/components/atoms/NavigatorButton.tsx b/src/components/atoms/NavigatorButton.tsx index e5e113678a..c10c4a4885 100644 --- a/src/components/atoms/NavigatorButton.tsx +++ b/src/components/atoms/NavigatorButton.tsx @@ -3,8 +3,9 @@ import styled from '../../lib/styled' import Icon from './Icon' const ButtonContainer = styled.button` - height: 24px; width: 24px; + height: 24px; + font-size: 18px; display: flex; align-items: center; justify-content: center; @@ -12,6 +13,7 @@ const ButtonContainer = styled.button` background-color: transparent; border-radius: 50%; border: none; + cursor: pointer; transition: color 200ms ease-in-out; color: ${({ theme }) => theme.sideNavButtonColor}; diff --git a/src/components/atoms/NavigatorItem.tsx b/src/components/atoms/NavigatorItem.tsx index c418dde38a..d353c1e97e 100644 --- a/src/components/atoms/NavigatorItem.tsx +++ b/src/components/atoms/NavigatorItem.tsx @@ -76,11 +76,12 @@ const Control = styled.div` top: 5px; ` -const SideNavigatorItemIconContainer = styled.span` - padding-right: 6px; +const IconContainer = styled.span` + padding-right: 0.2em; + font-size: 18px; ` -interface SideNaviagtorItemProps { +interface NavigatorItemProps { label: string iconPath?: string depth: number @@ -97,7 +98,7 @@ interface SideNaviagtorItemProps { onDoubleClick?: (event: React.MouseEvent) => void } -const SideNaviagtorItem = ({ +const NavigatorItem = ({ label, iconPath, depth, @@ -112,7 +113,7 @@ const SideNaviagtorItem = ({ onDrop, onDragOver, onDragEnd, -}: SideNaviagtorItemProps) => { +}: NavigatorItemProps) => { return ( - {folded ? ( - - ) : ( - - )} + )} {iconPath != null && ( - + - + )} @@ -154,4 +151,4 @@ const SideNaviagtorItem = ({ ) } -export default SideNaviagtorItem +export default NavigatorItem diff --git a/src/components/molecules/FolderListFragment.tsx b/src/components/molecules/FolderListFragment.tsx index b3781b4b0f..0af7a16430 100644 --- a/src/components/molecules/FolderListFragment.tsx +++ b/src/components/molecules/FolderListFragment.tsx @@ -9,7 +9,7 @@ import { useGeneralStatus } from '../../lib/generalStatus' import { getFolderItemId } from '../../lib/nav' import { getTransferrableNoteData } from '../../lib/dnd' import { useTranslation } from 'react-i18next' -import { mdiFolderOutline, mdiFolderOpenOutline, mdiPlus } from '@mdi/js' +import { mdiPlus, mdiFolderOpen, mdiFolder } from '@mdi/js' import NavigatorButton from '../atoms/NavigatorButton' interface FolderListFragmentProps { @@ -192,7 +192,7 @@ const FolderListFragment = ({ folded={folded} depth={depth} active={folderIsActive} - iconPath={folderIsActive ? mdiFolderOpenOutline : mdiFolderOutline} + iconPath={folderIsActive ? mdiFolderOpen : mdiFolder} label={folderName} onClick={createOnFolderItemClickHandler(folderPathname)} onDoubleClick={() => showPromptToRenameFolder(folderPathname)} diff --git a/src/components/molecules/StorageNavigatorFragment.tsx b/src/components/molecules/StorageNavigatorFragment.tsx index cdfcfd6399..8a079c59eb 100644 --- a/src/components/molecules/StorageNavigatorFragment.tsx +++ b/src/components/molecules/StorageNavigatorFragment.tsx @@ -12,11 +12,11 @@ import NavigatorItem from '../atoms/NavigatorItem' import { NoteStorage } from '../../lib/db/types' import { mdiTrashCanOutline, - mdiBookOpenOutline, mdiPaperclip, mdiTuneVertical, - mdiCloudOutline, mdiPlus, + mdiCloud, + mdiBookOpen, } from '@mdi/js' import FolderListFragment from './FolderListFragment' import TagListFragment from './TagListFragment' @@ -183,7 +183,7 @@ const StorageNavigatorFragment = ({ } syncStorage(storage.id) }} - iconPath={mdiCloudOutline} + iconPath={mdiCloud} /> push(`/app/storages/${storage.id}`)} @@ -195,7 +195,7 @@ const StorageNavigatorFragment = ({ push(allNotesPagePathname)} /> diff --git a/src/components/molecules/TagListFragment.tsx b/src/components/molecules/TagListFragment.tsx index df02cc0e5e..a0aef4698a 100644 --- a/src/components/molecules/TagListFragment.tsx +++ b/src/components/molecules/TagListFragment.tsx @@ -8,7 +8,7 @@ import { useContextMenu, MenuTypes } from '../../lib/contextMenu' import { useDialog, DialogIconTypes } from '../../lib/dialog' import { useDb } from '../../lib/db' import { useTranslation } from 'react-i18next' -import { mdiTagMultipleOutline, mdiPound } from '@mdi/js' +import { mdiPound, mdiTagMultiple } from '@mdi/js' interface TagListFragmentProps { storage: NoteStorage @@ -87,7 +87,7 @@ const TagListFragment = ({ storage }: TagListFragmentProps) => { <> 0 ? tagListIsFolded : undefined} onFoldButtonClick={() => { From b19be72cfc4a6b10b3e35e02b8f862eef9600742 Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Sun, 19 Apr 2020 21:20:00 +0900 Subject: [PATCH 31/53] Improve top control UI of nav --- src/components/atoms/NavigatorButton.tsx | 3 +++ src/components/organisms/Navigator.tsx | 10 ++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/atoms/NavigatorButton.tsx b/src/components/atoms/NavigatorButton.tsx index c10c4a4885..f9043377e2 100644 --- a/src/components/atoms/NavigatorButton.tsx +++ b/src/components/atoms/NavigatorButton.tsx @@ -32,6 +32,7 @@ interface NavigatorButtonProps { onClick?: React.MouseEventHandler onContextMenu?: React.MouseEventHandler iconPath: string + title?: string } const NavigatorButton = ({ @@ -39,11 +40,13 @@ const NavigatorButton = ({ onClick, onContextMenu, iconPath, + title, }: NavigatorButtonProps) => { return ( diff --git a/src/components/organisms/Navigator.tsx b/src/components/organisms/Navigator.tsx index 6f4a1d7dc7..e85458abfb 100644 --- a/src/components/organisms/Navigator.tsx +++ b/src/components/organisms/Navigator.tsx @@ -21,6 +21,7 @@ const NavigatorContainer = styled.nav` const TopControl = styled.div` display: flex; + margin: 1em 0; ` const Empty = styled.button` @@ -86,11 +87,16 @@ const Navigator = () => { push('/app/storages')} - iconPath={mdiPlus} /> - +
From d0549b15b2fbd7dcdf3abfdb6ecb33ec0259d39e Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Sun, 19 Apr 2020 21:29:09 +0900 Subject: [PATCH 32/53] Fix vertical position of icon of nav item --- src/components/atoms/NavigatorItem.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/atoms/NavigatorItem.tsx b/src/components/atoms/NavigatorItem.tsx index d353c1e97e..e6483477ea 100644 --- a/src/components/atoms/NavigatorItem.tsx +++ b/src/components/atoms/NavigatorItem.tsx @@ -76,8 +76,11 @@ const Control = styled.div` top: 5px; ` -const IconContainer = styled.span` - padding-right: 0.2em; +const IconContainer = styled.div` + width: 22px; + height: 24px; + display: flex; + align-items: center; font-size: 18px; ` From 5495c47729116cae21388a9b928ffe0c2c3f26a5 Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Sun, 19 Apr 2020 21:29:36 +0900 Subject: [PATCH 33/53] Add style prop to Icon --- src/components/atoms/Icon.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/atoms/Icon.tsx b/src/components/atoms/Icon.tsx index adda5ae2bd..094fa74b66 100644 --- a/src/components/atoms/Icon.tsx +++ b/src/components/atoms/Icon.tsx @@ -5,13 +5,14 @@ interface IconProps { path: string color?: string size?: number + style?: React.CSSProperties } -const Icon = ({ path, color = 'currentColor', size }: IconProps) => ( +const Icon = ({ path, color = 'currentColor', size, style }: IconProps) => ( ( : { width: `${size}px`, height: `${size}px`, - } - } + }), + ...style, + }} color={color} /> ) From 5f30314b4e97374ac1a013f897b4648e23f15f44 Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Sun, 19 Apr 2020 21:54:14 +0900 Subject: [PATCH 34/53] Fix light theme coloring --- src/themes/light.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/themes/light.ts b/src/themes/light.ts index 17c54fc834..f7b2d84418 100644 --- a/src/themes/light.ts +++ b/src/themes/light.ts @@ -47,16 +47,16 @@ export const lightTheme: BaseTheme = { // SideBar sideNavBackgroundColor: '#fff', - sideNavLabelColor: '#555', - sideNavButtonColor: '#777', - sideNavButtonHoverColor: '#555', + sideNavLabelColor: '#808080', + sideNavButtonColor: '#999', + sideNavButtonHoverColor: '#808080', sideNavButtonActiveColor: primaryColor, - sideNavItemColor: '#555', + sideNavItemColor: '#808080', sideNavItemBackgroundColor: 'transparent', - sideNavItemHoverBackgroundColor: '#eee', - sideNavItemActiveColor: '#111', - sideNavItemActiveBackgroundColor: '#eee', - sideNavItemHoverActiveBackgroundColor: '#e0e0e0', + sideNavItemHoverBackgroundColor: '#e4e4e4', + sideNavItemActiveColor: '#555', + sideNavItemActiveBackgroundColor: '#e4e4e4', + sideNavItemHoverActiveBackgroundColor: '#d4d4d4', // Button primaryButtonLabelColor: light100Color, From 9da9512300db9b1b2469475e9e7da384dab1fb35 Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Sun, 19 Apr 2020 22:35:57 +0900 Subject: [PATCH 35/53] Improve routing - Rename storages.edit to storages.settings - Discard deprecated routing --- src/components/Router.tsx | 3 +- .../molecules/StorageNavigatorFragment.tsx | 2 +- src/lib/router/types.ts | 12 ++---- src/lib/router/utils.ts | 37 +++++-------------- src/mobile/components/Router.tsx | 2 +- src/mobile/lib/router.ts | 18 ++++----- 6 files changed, 25 insertions(+), 49 deletions(-) diff --git a/src/components/Router.tsx b/src/components/Router.tsx index 527c103097..0ac78b45e4 100644 --- a/src/components/Router.tsx +++ b/src/components/Router.tsx @@ -19,7 +19,6 @@ export default () => { useRedirectHandler() switch (routeParams.name) { - case 'storages.bookmarks': case 'storages.notes': case 'storages.trashCan': case 'storages.tags.show': @@ -28,7 +27,7 @@ export default () => { return case 'storages.create': return - case 'storages.edit': + case 'storages.settings': const storage = db.storageMap[routeParams.storageId] if (storage != null) { return diff --git a/src/components/molecules/StorageNavigatorFragment.tsx b/src/components/molecules/StorageNavigatorFragment.tsx index 8a079c59eb..e53ad8f268 100644 --- a/src/components/molecules/StorageNavigatorFragment.tsx +++ b/src/components/molecules/StorageNavigatorFragment.tsx @@ -186,7 +186,7 @@ const StorageNavigatorFragment = ({ iconPath={mdiCloud} /> push(`/app/storages/${storage.id}`)} + onClick={() => push(`/app/storages/${storage.id}/settings`)} iconPath={mdiTuneVertical} /> diff --git a/src/lib/router/types.ts b/src/lib/router/types.ts index f87c29eaab..2b08b015db 100644 --- a/src/lib/router/types.ts +++ b/src/lib/router/types.ts @@ -14,8 +14,8 @@ export interface StorageCreate extends BaseRouteParams { name: 'storages.create' } -export interface StorageEdit extends BaseRouteParams { - name: 'storages.edit' +export interface StorageSettings extends BaseRouteParams { + name: 'storages.settings' storageId: string } @@ -50,22 +50,16 @@ export interface StorageAttachmentsRouteParams extends BaseRouteParams { storageId: string } -export interface TutorialsRouteParams extends BaseRouteParams { - name: 'tutorials.show' - path: string -} - export interface UnknownRouteparams extends BaseRouteParams { name: 'unknown' } export type AllRouteParams = | StorageCreate - | StorageEdit + | StorageSettings | StorageBookmarkNotes | StorageNotesRouteParams | StorageTrashCanRouteParams | StorageTagsRouteParams | StorageAttachmentsRouteParams | UnknownRouteparams - | TutorialsRouteParams diff --git a/src/lib/router/utils.ts b/src/lib/router/utils.ts index d876b6ac7d..5612b978ba 100644 --- a/src/lib/router/utils.ts +++ b/src/lib/router/utils.ts @@ -43,40 +43,34 @@ export const useRouteParams = () => { return useMemo((): AllRouteParams => { const names = pathname.slice('/app'.length).split('/').slice(1) - let noteId: string | undefined = undefined - if (names[0] === 'bookmarks') { - return { - name: 'storages.bookmarks', - } - } - if (names[0] === 'storages' && names[1] == null) { return { name: 'storages.create', } } - if (names[0] === 'tutorials') { - return { - name: 'tutorials.show', - path: pathname, - } - } - if (names[0] !== 'storages' || names[1] == null) { return { name: 'unknown', } } const storageId = names[1] + if (names[2] == null || names[2].length === 0) { + return { + name: 'storages.notes', + storageId, + folderPathname: '/', + } + } - if (names[2] == null) { + if (names[2] === 'settings') { return { - name: 'storages.edit', + name: 'storages.settings', storageId, } } + let noteId: string | undefined = undefined if (names[2] === 'notes') { const restNames = names.slice(3) if (restNames[0] == null || restNames[0] === '') { @@ -158,14 +152,3 @@ export const usePathnameWithoutNoteId = () => { return pathname }, [routeParams, pathname]) } - -export const useCurrentTutorialPathname = () => { - const routeParams = useRouteParams() - return useMemo(() => { - switch (routeParams.name) { - case 'tutorials.show': - return routeParams.path - } - return '/app' - }, [routeParams]) -} diff --git a/src/mobile/components/Router.tsx b/src/mobile/components/Router.tsx index 28d2cb5dea..dd0bf326b0 100644 --- a/src/mobile/components/Router.tsx +++ b/src/mobile/components/Router.tsx @@ -30,7 +30,7 @@ export default () => { // return case 'storages.create': return - case 'storages.edit': + case 'storages.settings': const storage = db.storageMap[routeParams.storageId] if (storage != null) { return diff --git a/src/mobile/lib/router.ts b/src/mobile/lib/router.ts index 991412f9e8..395484a0fa 100644 --- a/src/mobile/lib/router.ts +++ b/src/mobile/lib/router.ts @@ -83,23 +83,23 @@ export const useRouteParams = () => { } } - if (names[0] === 'tutorials') { - return { - name: 'tutorials.show', - path: pathname, - } - } - if (names[0] !== 'storages' || names[1] == null) { return { name: 'unknown', } } const storageId = names[1] + if (names[2] == null || names[2].length === 0) { + return { + name: 'storages.notes', + storageId, + folderPathname: '/', + } + } - if (names[2] == null) { + if (names[2] == 'settings') { return { - name: 'storages.edit', + name: 'storages.settings', storageId, } } From 80bfd01c79bd88d3e22bfb64fbee727265037c7b Mon Sep 17 00:00:00 2001 From: Junyoung Choi Date: Mon, 20 Apr 2020 00:21:44 +0900 Subject: [PATCH 36/53] Improve NoteList coloring --- src/components/atoms/Icon.tsx | 10 ++- src/components/organisms/NoteList.tsx | 123 ++++++++++++++++---------- src/lib/styled/styleFunctions.ts | 14 +-- src/themes/light.ts | 36 +++++--- 4 files changed, 117 insertions(+), 66 deletions(-) diff --git a/src/components/atoms/Icon.tsx b/src/components/atoms/Icon.tsx index 094fa74b66..3d6648e714 100644 --- a/src/components/atoms/Icon.tsx +++ b/src/components/atoms/Icon.tsx @@ -6,9 +6,16 @@ interface IconProps { color?: string size?: number style?: React.CSSProperties + className?: string } -const Icon = ({ path, color = 'currentColor', size, style }: IconProps) => ( +const Icon = ({ + path, + color = 'currentColor', + size, + style, + className, +}: IconProps) => ( ( ...style, }} color={color} + className={className} /> ) diff --git a/src/components/organisms/NoteList.tsx b/src/components/organisms/NoteList.tsx index 9c3371746c..f5d45d3eea 100644 --- a/src/components/organisms/NoteList.tsx +++ b/src/components/organisms/NoteList.tsx @@ -4,12 +4,11 @@ import { PopulatedNoteDoc } from '../../lib/db/types' import styled from '../../lib/styled' import { borderBottom, - inputStyle, noteListIconColor, selectTabStyle, disabledUiTextColor, + inputStyle, } from '../../lib/styled/styleFunctions' -import { IconEdit, IconLoupe } from '../icons' import { useTranslation } from 'react-i18next' import { useGlobalKeyDownHandler, @@ -18,9 +17,9 @@ import { import { NoteListSortOptions } from '../pages/NotePage' import { osName } from '../../lib/platform' import Icon from '../atoms/Icon' -import { mdiChevronDown } from '@mdi/js' +import { mdiChevronDown, mdiPlus, mdiMagnify } from '@mdi/js' -export const StyledNoteListContainer = styled.div` +const NoteListContainer = styled.div` display: flex; flex-direction: column; overflow: hidden; @@ -34,46 +33,11 @@ export const StyledNoteListContainer = styled.div` overflow-y: auto; } - .control { - height: 50px; - display: flex; - padding: 8px; - align-items: center; - -webkit-app-region: drag; - ${borderBottom} - } - - .searchInput { - flex: 1; - position: relative; - height: 32px; - .icon { - position: absolute; - top: 8px; - left: 10px; - font-size: 20px; - z-index: 0; - pointer-events: none; - ${noteListIconColor} - } - .input { - position: relative; - width: 100%; - height: 32px; - padding-left: 35px; - box-sizing: border-box; - ${inputStyle} - } - select { - appearance: none; - } - } - .filterTab { height: 25px; display: flex; align-items: center; - padding-left: 13px; + padding-left: 1em; .filterIcon { font-size: 10px; margin-right: 5px; @@ -110,6 +74,73 @@ export const StyledNoteListContainer = styled.div` } ` +const Control = styled.div` + height: 50px; + display: flex; + padding: 0 0 0 8px; + align-items: center; + -webkit-app-region: drag; + ${borderBottom} + .newNoteButton { + width: 36px; + height: 36px; + font-size: 18px; + display: flex; + align-items: center; + justify-content: center; + + background-color: transparent; + border-radius: 50%; + border: none; + cursor: pointer; + + transition: color 200ms ease-in-out; + color: ${({ theme }) => theme.sideNavButtonColor}; + &:hover { + color: ${({ theme }) => theme.sideNavButtonHoverColor}; + } + + &:active, + .active { + color: ${({ theme }) => theme.sideNavButtonActiveColor}; + } + } + + .searchInput { + ${inputStyle} + flex: 1; + position: relative; + height: 32px; + color: ${({ theme }) => theme.sideNavButtonColor}; + border-radius: 4px; + overflow: hidden; + &:focus { + box-shadow: 0 0 0 2px ${({ theme }) => theme.primaryColor}; + } + .icon { + position: absolute; + top: 6px; + left: 10px; + font-size: 18px; + z-index: 0; + pointer-events: none; + ${noteListIconColor} + } + .input { + background-color: transparent; + position: relative; + width: 100%; + height: 30px; + padding-left: 35px; + box-sizing: border-box; + border: none; + } + select { + appearance: none; + } + } +` + type NoteListProps = { currentStorageId?: string currentNoteId?: string @@ -199,8 +230,8 @@ const NoteList = ({ ) return ( - -
+ +
- +
{currentStorageId != null && createNote != null && ( )} -
+