Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"scripts": {
"dev": "env-cmd cross-env NODE_ENV=development TS_NODE_PROJECT=\"tsconfig-webpack.json\" webpack-dev-server --mode development --open-page \"app\"",
"dev:app": "npm run build:electron && npm run start",
"start": "electron app/index.js",
"lint": "eslint src/* --ext .ts,.tsx",
"format": "prettier --write \"src/**/*\"",
Expand Down
73 changes: 38 additions & 35 deletions src/components/NotePage/NoteList/NoteList.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import React, {
useCallback,
KeyboardEvent,
useRef,
ChangeEventHandler,
useMemo,
useState
} from 'react'
import React, { useCallback, useRef, ChangeEventHandler } from 'react'
import NoteItem from './NoteItem'
import { PopulatedNoteDoc } from '../../../lib/db/types'
import styled from '../../../lib/styled'
Expand All @@ -17,6 +10,11 @@ import {
} from '../../../lib/styled/styleFunctions'
import { IconEdit, IconLoupe, IconArrowSingleDown } from '../../icons'
import { useTranslation } from 'react-i18next'
import {
useGlobalKeyDownHandler,
isWithGeneralCtrlKey
} from '../../../lib/keyboard'
import { NoteListSortOptions } from '../NotePage'

export const StyledNoteListContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -98,8 +96,6 @@ export const StyledNoteListContainer = styled.div`
}
`

type SortProps = 'createdAt' | 'title' | 'updatedAt'

type NoteListProps = {
currentStorageId?: string
currentNoteId?: string
Expand All @@ -111,6 +107,7 @@ type NoteListProps = {
navigateUp: () => void
basePathname: string
lastCreatedNoteId: string
setSort: (option: NoteListSortOptions) => void
}

const NoteList = ({
Expand All @@ -123,7 +120,8 @@ const NoteList = ({
setSearchInput,
navigateDown,
navigateUp,
lastCreatedNoteId
lastCreatedNoteId,
setSort
}: NoteListProps) => {
const { t } = useTranslation()
const updateSearchInput: ChangeEventHandler<HTMLInputElement> = useCallback(
Expand All @@ -132,31 +130,35 @@ const NoteList = ({
},
[setSearchInput]
)
const [sort, setSort] = useState<SortProps>('updatedAt')

const sortedNotes = useMemo(() => {
return notes.sort((first, second) => {
return sort === 'title'
? first[sort].localeCompare(second[sort])
: second[sort].localeCompare(first[sort])
})
}, [notes, sort])
const listRef = useRef<HTMLUListElement>(null)
const searchRef = useRef<HTMLInputElement>(null)

const handleListKeyDown = useCallback(
(event: KeyboardEvent) => {
switch (event.key) {
case 'ArrowDown':
useGlobalKeyDownHandler(e => {
switch (e.key) {
case 's':
if (isWithGeneralCtrlKey(e) && !e.shiftKey) {
searchRef.current!.focus()
}
break
case 'j':
if (isWithGeneralCtrlKey(e)) {
e.preventDefault()
e.stopPropagation()
navigateDown()
break
case 'ArrowUp':
}
break
case 'k':
if (isWithGeneralCtrlKey(e)) {
e.preventDefault()
e.stopPropagation()
navigateUp()
break
}
},
[navigateUp, navigateDown]
)

const listRef = useRef<HTMLUListElement>(null)
}
break
default:
break
}
})

const focusList = useCallback(() => {
listRef.current!.focus()
Expand All @@ -166,6 +168,7 @@ const NoteList = ({
<div className='control'>
<div className='searchInput'>
<input
ref={searchRef}
className='input'
value={search}
onChange={updateSearchInput}
Expand All @@ -183,15 +186,15 @@ const NoteList = ({
<IconArrowSingleDown className='filterIcon' size='0.8em' />
<select
className='input'
onChange={e => setSort(e.target.value as SortProps)}
onChange={e => setSort(e.target.value as NoteListSortOptions)}
>
<option value='updatedAt'>Updated</option>
<option value='createdAt'>Created</option>
<option value='title'>Title</option>
</select>
</div>
<ul tabIndex={0} onKeyDown={handleListKeyDown} ref={listRef}>
{sortedNotes.map(note => {
<ul tabIndex={0} ref={listRef}>
{notes.map(note => {
const noteIsCurrentNote = note._id === currentNoteId
return (
<li key={note._id}>
Expand Down
75 changes: 63 additions & 12 deletions src/components/NotePage/NotePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import { useGeneralStatus, ViewModeType } from '../../lib/generalStatus'
import { useDialog, DialogIconTypes } from '../../lib/dialog'
import { escapeRegExp } from '../../lib/regex'
import { useTranslation } from 'react-i18next'
import {
useGlobalKeyDownHandler,
isWithGeneralCtrlKey
} from '../../lib/keyboard'

export const StyledNoteDetailNoNote = styled.div`
text-align: center;
Expand All @@ -31,6 +35,8 @@ export type BreadCrumbs = {
folderIsActive: boolean
}[]

export type NoteListSortOptions = 'createdAt' | 'title' | 'updatedAt'

export default () => {
const db = useDb()

Expand All @@ -46,12 +52,12 @@ export default () => {
return db.storageMap[storageId]
}, [db.storageMap, storageId])
const router = useRouter()
const { t } = useTranslation()
const [search, setSearchInput] = useState<string>('')
const currentPathnameWithoutNoteId = usePathnameWithoutNoteId()
const { push } = useRouter()
const [lastCreatedNoteId, setLastCreatedNoteId] = useState<string>('')

const { t } = useTranslation()
const [sort, setSort] = useState<NoteListSortOptions>('updatedAt')

useEffect(() => {
setLastCreatedNoteId('')
Expand Down Expand Up @@ -119,15 +125,22 @@ export default () => {
}, [db.storageMap, currentStorage, routeParams])

const filteredNotes = useMemo(() => {
if (search.trim() === '') return notes
const regex = new RegExp(escapeRegExp(search), 'i')
return notes.filter(
note =>
note.tags.join().match(regex) ||
note.title.match(regex) ||
note.content.match(regex)
)
}, [search, notes])
let filteredNotes = notes
if (search.trim() != '') {
const regex = new RegExp(escapeRegExp(search), 'i')
filteredNotes = notes.filter(
note =>
note.tags.join().match(regex) ||
note.title.match(regex) ||
note.content.match(regex)
)
}
return filteredNotes.sort((first, second) => {
return sort === 'title'
? first[sort].localeCompare(second[sort])
: second[sort].localeCompare(first[sort])
})
}, [search, notes, sort])

const currentNoteIndex = useMemo(() => {
for (let i = 0; i < filteredNotes.length; i++) {
Expand All @@ -139,7 +152,9 @@ export default () => {
}, [filteredNotes, noteId])

const currentNote: PopulatedNoteDoc | undefined = useMemo(() => {
return filteredNotes[currentNoteIndex]
return filteredNotes[currentNoteIndex] != null
? filteredNotes[currentNoteIndex]
: undefined
}, [filteredNotes, currentNoteIndex])

const createNote = useCallback(async () => {
Expand Down Expand Up @@ -245,6 +260,41 @@ export default () => {
}
}, [filteredNotes, currentNoteIndex, router, currentPathnameWithoutNoteId])

useGlobalKeyDownHandler(e => {
switch (e.key) {
case 'Backspace':
if (currentNote != null && isWithGeneralCtrlKey(e)) {
if (!currentNote.trashed) {
db.trashNote(currentNote.storageId, currentNote._id)
} else {
purgeNote(currentNote.storageId, currentNote._id)
}
}
break
case 'n':
if (isWithGeneralCtrlKey(e)) {
createNote()
}
break
case 'T':
case 't':
if (isWithGeneralCtrlKey(e) && e.shiftKey) {
switch (generalStatus['noteViewMode']) {
case 'edit':
toggleViewMode('split')
break
case 'split':
toggleViewMode('preview')
break
default:
toggleViewMode('edit')
break
}
}
break
}
})

return (
<TwoPaneLayout
style={{ height: '100%' }}
Expand All @@ -261,6 +311,7 @@ export default () => {
navigateUp={navigateUp}
currentNoteId={currentNote ? currentNote._id : undefined}
lastCreatedNoteId={lastCreatedNoteId}
setSort={setSort}
/>
}
right={
Expand Down
3 changes: 2 additions & 1 deletion src/components/PreferencesModal/PreferencesModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ const CloseButton = styled.button`
`

const PreferencesModal = () => {
const { t } = useTranslation()
const { closed, toggleClosed } = usePreferences()
const [tab, setTab] = useState('general')
const { t } = useTranslation()

const keydownHandler = useMemo(() => {
return (event: KeyboardEvent) => {
if (!closed && event.key === 'Escape') {
Expand Down
37 changes: 24 additions & 13 deletions src/components/Tutorials/TutorialsNoteList.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import React, { useCallback, KeyboardEvent, useRef } from 'react'
import React, { useCallback, useRef } from 'react'
import { TutorialsNavigatorTreeItem } from '../../lib/tutorials'
import TutorialsNoteItem from './TutorialsNoteItem'
import { StyledNoteListContainer } from '../NotePage/NoteList/NoteList'
import { useTranslation } from 'react-i18next'
import {
isWithGeneralCtrlKey,
useGlobalKeyDownHandler
} from '../../lib/keyboard'

type TutorialsNoteListProps = {
currentTree: TutorialsNavigatorTreeItem
Expand All @@ -21,19 +25,26 @@ const TutorialsNoteList = ({
basePathname,
selectedNote
}: TutorialsNoteListProps) => {
const handleListKeyDown = useCallback(
(event: KeyboardEvent) => {
switch (event.key) {
case 'ArrowDown':
useGlobalKeyDownHandler(e => {
switch (e.key) {
case 'j':
if (isWithGeneralCtrlKey(e)) {
e.preventDefault()
e.stopPropagation()
navigateDown()
break
case 'ArrowUp':
}
break
case 'k':
if (isWithGeneralCtrlKey(e)) {
e.preventDefault()
e.stopPropagation()
navigateUp()
break
}
},
[navigateUp, navigateDown]
)
}
break
default:
break
}
})

const listRef = useRef<HTMLUListElement>(null)

Expand All @@ -52,7 +63,7 @@ const TutorialsNoteList = ({

return (
<StyledNoteListContainer>
<ul tabIndex={0} onKeyDown={handleListKeyDown} ref={listRef}>
<ul tabIndex={0} ref={listRef}>
{notes.map(note => {
const noteIsCurrentNote =
selectedNote != null &&
Expand Down
4 changes: 2 additions & 2 deletions src/lib/i18n/enUS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ export default {
'note.nothingMessage': 'No notes could be found.',
'note.noTitle': 'No title',
'note.date': 'ago',
'note.createKeyMac': 'Mac: Command(⌘) + Enter',
'note.createKeyWinLin': 'Windows/Linux: Ctrl + Enter',
'note.createKeyMac': 'Mac: Command(⌘) + n',
'note.createKeyWinLin': 'Windows/Linux: Ctrl + n',
'note.createkeymessage1': 'to create a new note',
'note.createkeymessage2': 'Select a storage',
'note.createkeymessage3': 'to create a new note',
Expand Down
Loading