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
4 changes: 2 additions & 2 deletions src/cloud/components/DocPage/SharedDocPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import SyncStatus from '../Topbar/SyncStatus'
import PresenceIcons from '../Topbar/PresenceIcons'
import SharePageTopbar from '../SharePageTopBar'
import { SerializedDoc } from '../../interfaces/db/doc'
import MarkdownView from '../MarkdownView'
import Spinner from '../../../design/components/atoms/Spinner'
import ColoredBlock from '../../../design/components/atoms/ColoredBlock'
import CustomizedMarkdownPreviewer from '../MarkdownView/CustomizedMarkdownPreviewer'

interface SharedDocPageProps {
doc: SerializedDoc
Expand Down Expand Up @@ -88,7 +88,7 @@ const SharedDocPage = ({ doc, token }: SharedDocPageProps) => {
<>
<StyledTitle>{doc.title}</StyledTitle>
<StyledContent>
<MarkdownView
<CustomizedMarkdownPreviewer
content={content}
shortcodeHandler={() => (
<span style={{ color: 'red' }}>
Expand Down
8 changes: 4 additions & 4 deletions src/cloud/components/Editor/EditorThemeSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const EditorThemeSelect = () => {
[]
)

const selectIndentType = useCallback(
const selectEditorTheme = useCallback(
(val: string) => {
setSettings({
'general.editorTheme': val as CodeMirrorEditorTheme,
Expand All @@ -70,7 +70,7 @@ const EditorThemeSelect = () => {
[setSettings]
)

const selectIndentSize = useCallback(
const selectCodeBlockTheme = useCallback(
(val: string) => {
setSettings({
'general.codeBlockTheme': val as CodeMirrorEditorTheme,
Expand Down Expand Up @@ -108,7 +108,7 @@ const EditorThemeSelect = () => {
>
<FormRowItem>
<SimpleFormSelect
onChange={selectIndentType}
onChange={selectEditorTheme}
id='editorTheme'
className='menu__item__select'
value={editorTheme}
Expand All @@ -129,7 +129,7 @@ const EditorThemeSelect = () => {
>
<FormRowItem>
<SimpleFormSelect
onChange={selectIndentSize}
onChange={selectCodeBlockTheme}
id='codeBlockTheme'
className='menu__item__select'
value={codeBlockTheme}
Expand Down
5 changes: 3 additions & 2 deletions src/cloud/components/Editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import {
} from '../../lib/utils/events'
import { ScrollSync, scrollSyncer } from '../../lib/editor/scrollSync'
import CodeMirrorEditor from '../../lib/editor/components/CodeMirrorEditor'
import MarkdownView, { SelectionContext } from '../MarkdownView'
import { SelectionContext } from '../MarkdownView'
import { usePage } from '../../lib/stores/pageStore'
import { useToast } from '../../../design/lib/stores/toast'
import { LoadingButton } from '../../../design/components/atoms/Button'
Expand Down Expand Up @@ -102,6 +102,7 @@ import {
paidPlanUploadSizeMb,
} from '../../lib/subscription'
import { nginxSizeLimitInMb } from '../../lib/upload'
import CustomizedMarkdownPreviewer from '../MarkdownView/CustomizedMarkdownPreviewer'

type LayoutMode = 'split' | 'preview' | 'editor'

Expand Down Expand Up @@ -1115,7 +1116,7 @@ const Editor = ({
</>
</StyledEditorWrapper>
<StyledPreview className={`layout-${editorLayout}`}>
<MarkdownView
<CustomizedMarkdownPreviewer
content={editorContent}
updateContent={setEditorRefContent}
headerLinks={editorLayout === 'preview'}
Expand Down
66 changes: 66 additions & 0 deletions src/cloud/components/MarkdownView/CustomizedMarkdownPreviewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from 'react'
import MarkdownView, { SelectionState } from './index'
import { usePreviewStyle } from '../../../lib/preview'
import { EmbedDoc } from '../../lib/docEmbedPlugin'
import { HighlightRange } from '../../lib/rehypeHighlight'
import { useSettings } from '../../lib/stores/settings'

interface CustomizedMarkdownViewProps {
content: string
customBlockRenderer?: (name: string) => JSX.Element
updateContent?: (
newContentOrUpdater: string | ((newValue: string) => string)
) => void
shortcodeHandler?: ({ identifier, entityId }: any) => JSX.Element
headerLinks?: boolean
onRender?: () => void
className?: string
getEmbed?: (
id: string
) => Promise<EmbedDoc | undefined> | EmbedDoc | undefined
scrollerRef?: React.RefObject<HTMLDivElement>
SelectionMenu?: React.ComponentType<{ selection: SelectionState['context'] }>
comments?: HighlightRange[]
commentClick?: (id: string[]) => void
codeFence?: boolean
previewStyle?: string
}

const CustomizedMarkdownPreviewer = ({
content,
updateContent,
shortcodeHandler,
headerLinks = true,
onRender,
className,
getEmbed,
scrollerRef,
SelectionMenu,
comments,
commentClick,
codeFence = true,
}: CustomizedMarkdownViewProps) => {
const { previewStyle } = usePreviewStyle()
const { settings } = useSettings()

return (
<MarkdownView
content={content}
updateContent={updateContent}
shortcodeHandler={shortcodeHandler}
headerLinks={headerLinks}
onRender={onRender}
className={className}
getEmbed={getEmbed}
scrollerRef={scrollerRef}
SelectionMenu={SelectionMenu}
comments={comments}
commentClick={commentClick}
codeFence={codeFence}
previewStyle={previewStyle}
codeBlockTheme={settings['general.codeBlockTheme']}
/>
)
}

export default CustomizedMarkdownPreviewer
109 changes: 61 additions & 48 deletions src/cloud/components/MarkdownView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import rehypeSanitize from 'rehype-sanitize'
import rehypeCodeMirror from '../../../design/lib/codemirror/rehypeCodeMirror'
import rehypeSlug from 'rehype-slug'
import { useEffectOnce } from 'react-use'
import { defaultPreviewStyle } from './styles'
import { useSettings } from '../../lib/stores/settings'
import { CodeMirrorEditorTheme } from '../../lib/stores/settings'
import {
remarkCharts,
Flowchart,
Expand Down Expand Up @@ -47,6 +46,7 @@ import CodeFence from '../../../design/components/atoms/markdown/CodeFence'
import { agentType, sendPostMessage } from '../../../mobile/lib/nativeMobile'
import { TableOfContents } from './TableOfContents'
import ExpandableImage from '../../../design/components/molecules/Image/ExpandableImage'
import { defaultPreviewStyle } from './styles'

const remarkAdmonitionOptions = {
tag: ':::',
Expand Down Expand Up @@ -96,7 +96,7 @@ export interface SelectionContext {
text: string
}

interface SelectionState {
export interface SelectionState {
context: SelectionContext
position: Rect
selection: Selection
Expand All @@ -119,6 +119,9 @@ interface MarkdownViewProps {
SelectionMenu?: React.ComponentType<{ selection: SelectionState['context'] }>
comments?: HighlightRange[]
commentClick?: (id: string[]) => void
codeFence?: boolean
previewStyle?: string
codeBlockTheme?: CodeMirrorEditorTheme
}

const MarkdownView = ({
Expand All @@ -133,10 +136,12 @@ const MarkdownView = ({
SelectionMenu,
comments,
commentClick,
codeFence = true,
previewStyle,
codeBlockTheme = 'default',
}: MarkdownViewProps) => {
const [state, setState] = useState<MarkdownViewState>({ type: 'loading' })
const modeLoadCallbackRef = useRef<() => any>()
const { settings } = useSettings()
const checkboxIndexRef = useRef<number>(0)
const onRenderRef = useRef(onRender)
const { push } = useRouter()
Expand Down Expand Up @@ -246,10 +251,13 @@ const MarkdownView = ({
</div>
) : null
},
pre: CodeFence,
},
}

if (codeFence) {
rehypeReactConfig.components.pre = CodeFence
}

if (headerLinks) {
rehypeReactConfig.components.h1 = linkableHeader('h1')
rehypeReactConfig.components.h2 = linkableHeader('h2')
Expand Down Expand Up @@ -281,7 +289,7 @@ const MarkdownView = ({
.use(rehypeKatex)
.use(rehypeCodeMirror, {
ignoreMissing: true,
theme: settings['general.codeBlockTheme'],
theme: codeBlockTheme,
})
.use(rehypeMermaid)
.use(rehypeHighlight, comments || [])
Expand All @@ -291,13 +299,14 @@ const MarkdownView = ({

return parser
}, [
content,
settings,
updateContent,
shortcodeHandler,
codeFence,
headerLinks,
getEmbed,
codeBlockTheme,
comments,
updateContent,
content,
commentClick,
])

Expand Down Expand Up @@ -394,6 +403,49 @@ const MarkdownView = ({
}
}, [selectionInfo])

const StyledMarkdownPreview = useMemo(() => {
return styled.div`
position: relative;
${defaultPreviewStyle};
${previewStyle};

padding: 0 ${({ theme }) => theme.sizes.spaces.md}px
${({ theme }) => theme.sizes.spaces.xl}px;

.block__gutter {
position: absolute;
left: 100%;
top: 0;
max-width: 40px;
}

.with__gutter {
position: relative;
}

.comment__count {
height: 20px;
display: flex;
align-items: flex-start;
color: ${({ theme }) => theme.colors.icon.default};
font-size: ${({ theme }) => theme.sizes.fonts.md}px;

&:hover {
cursor: pointer;
color: ${({ theme }) => theme.colors.text.primary};
}

svg {
margin-right: ${({ theme }) => theme.sizes.spaces.xsm}px;
}
}

.comment__count__number {
line-height: 1;
}
`
}, [previewStyle])

return (
<StyledMarkdownPreview
className={className}
Expand Down Expand Up @@ -455,45 +507,6 @@ function isElement(node: Node): node is Element {
return node.nodeType === 1
}

const StyledMarkdownPreview = styled.div`
position: relative;
${defaultPreviewStyle}
padding: 0 ${({ theme }) => theme.sizes.spaces.md}px ${({ theme }) =>
theme.sizes.spaces.xl}px;

.block__gutter {
position: absolute;
left: 100%;
top: 0;
max-width: 40px;
}

.with__gutter {
position: relative;
}

.comment__count {
height: 20px;
display: flex;
align-items: flex-start;
color: ${({ theme }) => theme.colors.icon.default};
font-size: ${({ theme }) => theme.sizes.fonts.md}px;

&:hover {
cursor: pointer;
color: ${({ theme }) => theme.colors.text.primary}
}

svg {
margin-right: ${({ theme }) => theme.sizes.spaces.xsm}px;
}
}

.comment__count__number {
line-height: 1;
}
`

const StyledTooltipContent = styled.div`
background-color: ${({ theme }) => theme.colors.background.secondary};
border: 1px solid ${({ theme }) => theme.colors.border.second};
Expand Down
Loading