Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add editor width setting #91

Merged
merged 4 commits into from
Aug 30, 2021
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
2 changes: 1 addition & 1 deletion components/container/edit-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export const EditContainer = () => {
<NoteNav />
<DeleteAlert />
<section className="h-full">
<MainEditor />
<MainEditor note={note} />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like typescript didn't catch this because of the async import. Didn't notice any side effects when adding this.

</section>
</>
)
Expand Down
9 changes: 7 additions & 2 deletions components/editor/main-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import EditTitle from './edit-title'
import Editor, { EditorProps } from './editor'
import Backlinks from './backlinks'
import EditorState from 'libs/web/state/editor'
import UIState from 'libs/web/state/ui'
import { FC } from 'react'
import { NoteModel } from 'libs/shared/note'

Expand All @@ -12,14 +13,18 @@ const MainEditor: FC<
className?: string
}
> = ({
className = 'pt-40 px-6 m-auto h-full max-w-prose',
className,
note,
small,
...props
}) => {
const { settings: { settings } } = UIState.useContainer()
const editorWidthClass = (note?.editorsize ?? settings.editorsize) > 0 ? "max-w-4xl" : "max-w-prose"
const articleClassName = className || `pt-40 px-6 m-auto h-full ${editorWidthClass}`

return (
<EditorState.Provider initialState={note}>
<article className={className}>
<article className={articleClassName}>
<EditTitle readOnly={props.readOnly} />
<Editor {...props} />
{!small && <Backlinks />}
Expand Down
20 changes: 18 additions & 2 deletions components/portal/sidebar-menu/sidebar-menu-item.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { NOTE_PINNED } from 'libs/shared/meta'
import { EDITOR_SIZE, NOTE_PINNED } from 'libs/shared/meta'
import { NoteModel } from 'libs/shared/note'
import NoteState from 'libs/web/state/note'
import PortalState from 'libs/web/state/portal'
import { forwardRef, useCallback, useMemo } from 'react'
import { MenuItem } from '@material-ui/core'
import UIState from 'libs/web/state/ui'

export enum MENU_HANDLER_NAME {
REMOVE_NOTE,
COPY_LINK,
ADD_TO_FAVORITES,
REMOVE_FROM_FAVORITES,
TOGGLE_WIDTH,
}

export interface Item {
Expand All @@ -25,6 +27,7 @@ interface ItemProps {

export const SidebarMenuItem = forwardRef<HTMLLIElement, ItemProps>(
({ item }, ref) => {
const { settings: { settings } } = UIState.useContainer()
const { removeNote, mutateNote } = NoteState.useContainer()
const {
menu: { close, data },
Expand Down Expand Up @@ -63,15 +66,28 @@ export const SidebarMenuItem = forwardRef<HTMLLIElement, ItemProps>(
})
}
}, [close, data, mutateNote])

const toggleWidth = useCallback(() => {
close()
if (data?.id) {
const resolvedNoteWidth = data.editorsize ?? settings.editorsize
const editorSizesCount = Object.values(EDITOR_SIZE).length / 2 // contains both string & int values

mutateNote(data.id, {
editorsize: (resolvedNoteWidth + 1) % editorSizesCount,
})
}
}, [close, data, mutateNote, settings.editorsize])

const MENU_HANDLER = useMemo(
() => ({
[MENU_HANDLER_NAME.REMOVE_NOTE]: doRemoveNote,
[MENU_HANDLER_NAME.COPY_LINK]: doCopyLink,
[MENU_HANDLER_NAME.ADD_TO_FAVORITES]: doPinned,
[MENU_HANDLER_NAME.REMOVE_FROM_FAVORITES]: doUnpinned,
[MENU_HANDLER_NAME.TOGGLE_WIDTH]: toggleWidth,
}),
[doCopyLink, doPinned, doRemoveNote, doUnpinned]
[doCopyLink, doPinned, doRemoveNote, doUnpinned, toggleWidth]
)

return (
Expand Down
7 changes: 7 additions & 0 deletions components/portal/sidebar-menu/sidebar-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Menu } from '@material-ui/core'
import { FC, useMemo } from 'react'
import {
ClipboardCopyIcon,
SelectorIcon,
StarIcon,
TrashIcon,
} from '@heroicons/react/outline'
Expand Down Expand Up @@ -45,6 +46,12 @@ const SidebarMenu: FC = () => {
return item?.pinned === NOTE_PINNED.PINNED
},
},
{
text: t('Toggle width'),
// TODO: or SwitchHorizontal?
icon: <SelectorIcon style={{ transform: "rotate(90deg)" }} />,
handler: MENU_HANDLER_NAME.TOGGLE_WIDTH,
},
],
[t]
)
Expand Down
35 changes: 35 additions & 0 deletions components/settings/editor-width.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { FC, useCallback, ChangeEvent } from 'react'
import { MenuItem, TextField } from '@material-ui/core'
import router from 'next/router'
import { defaultFieldConfig } from './settings-container'
import useI18n from 'libs/web/hooks/use-i18n'
import UIState from 'libs/web/state/ui'
import { EDITOR_SIZE } from 'libs/shared/meta'

export const EditorWidth: FC = () => {
const { t } = useI18n()
const {
settings: { settings, updateSettings },
} = UIState.useContainer()

const handleChange = useCallback(
async (event: ChangeEvent<HTMLInputElement>) => {
await updateSettings({ editorsize: parseInt(event.target.value) })
router.reload()
},
[updateSettings]
)

return (
<TextField
{...defaultFieldConfig}
label={t('Default editor width')}
value={settings.editorsize ?? EDITOR_SIZE.SMALL}
onChange={handleChange}
select
>
<MenuItem value={EDITOR_SIZE.SMALL}>{t('Small (default)')}</MenuItem>
<MenuItem value={EDITOR_SIZE.LARGE}>{t('Large')}</MenuItem>
</TextField>
)
}
2 changes: 2 additions & 0 deletions components/settings/settings-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { FC } from 'react'
import { DailyNotes } from './daily-notes'
import { Language } from './language'
import { Theme } from './theme'
import { EditorWidth } from './editor-width'
import { ImportOrExport } from './import-or-export'
import { SnippetInjection } from './snippet-injection'
import useI18n from 'libs/web/hooks/use-i18n'
Expand Down Expand Up @@ -34,6 +35,7 @@ export const SettingsContainer: FC = () => {
<DailyNotes></DailyNotes>
<Language></Language>
<Theme></Theme>
<EditorWidth></EditorWidth>
<HR />
<SettingsHeader
id="import-and-export"
Expand Down
2 changes: 2 additions & 0 deletions libs/server/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export function metaToJson(metaData?: Record<string, any>) {
meta[key] = value ? strDecompress(value) : NOTE_SHARED.PRIVATE
} else if (key === 'pinned') {
meta[key] = value ? strDecompress(value) : NOTE_PINNED.UNPINNED
} else if (key === 'editorsize') {
meta[key] = value ? strDecompress(value) : null
}
})
}
Expand Down
8 changes: 7 additions & 1 deletion libs/shared/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export enum NOTE_PINNED {
PINNED,
}

export enum EDITOR_SIZE {
SMALL,
LARGE,
}

export const PAGE_META_KEY = <const>[
'title',
'pid',
Expand All @@ -22,8 +27,9 @@ export const PAGE_META_KEY = <const>[
'date',
'deleted',
'pinned',
'editorsize',
]

export type metaKey = typeof PAGE_META_KEY[number]

export const NUMBER_KEYS: metaKey[] = ['deleted', 'shared', 'pinned']
export const NUMBER_KEYS: metaKey[] = ['deleted', 'shared', 'pinned', 'editorsize']
3 changes: 2 additions & 1 deletion libs/shared/note.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NOTE_DELETED, NOTE_PINNED, NOTE_SHARED } from './meta'
import { EDITOR_SIZE, NOTE_DELETED, NOTE_PINNED, NOTE_SHARED } from './meta'

export interface NoteModel {
id: string
Expand All @@ -10,6 +10,7 @@ export interface NoteModel {
deleted: NOTE_DELETED
shared: NOTE_SHARED
pinned: NOTE_PINNED
editorsize: EDITOR_SIZE | null
}

/**
Expand Down
7 changes: 7 additions & 0 deletions libs/shared/settings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Locale } from 'locales'
import { isArray, isBoolean, isNumber, isString, values } from 'lodash'
import { EDITOR_SIZE } from './meta'
import { ROOT_ID } from './tree'

export interface Settings {
Expand All @@ -9,13 +10,15 @@ export interface Settings {
last_visit?: string
locale: Locale
injection?: string
editorsize: EDITOR_SIZE;
}

export const DEFAULT_SETTINGS: Settings = Object.freeze({
split_sizes: [30, 70],
daily_root_id: ROOT_ID,
sidebar_is_fold: false,
locale: Locale.EN,
editorsize: EDITOR_SIZE.SMALL,
})

export function formatSettings(body: Record<string, any> = {}) {
Expand Down Expand Up @@ -53,5 +56,9 @@ export function formatSettings(body: Record<string, any> = {}) {
settings.injection = body.injection
}

if (isNumber(body.editorsize)) {
settings.editorsize = body.editorsize
}

return settings
}
1 change: 1 addition & 0 deletions libs/web/state/note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ const useNote = (initData?: NoteModel) => {
deleted: NOTE_DELETED.NORMAL,
shared: NOTE_SHARED.PRIVATE,
pinned: NOTE_PINNED.UNPINNED,
editorsize: null,
id: '-1',
title: '',
...note,
Expand Down
Loading