Skip to content

Commit

Permalink
feat: Added "Page size" option when exporting Super notes as PDF
Browse files Browse the repository at this point in the history
  • Loading branch information
amanharwara committed Jan 27, 2024
1 parent ff3c45b commit 853fab5
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 26 deletions.
2 changes: 1 addition & 1 deletion packages/desktop/app/javascripts/Renderer/Renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ async function configureWindow(remoteBridge: CrossProcessBridge) {
/* Use custom title bar. Take the sn-titlebar-height off of
the app content height so its not overflowing */
sheet.insertRule(
'[role="dialog"]:not(.challenge-modal) { height: calc(100vh - var(--sn-desktop-titlebar-height)) !important; margin-top: var(--sn-desktop-titlebar-height); }',
'[role="dialog"]:not(.challenge-modal) { max-height: calc(100vh - var(--sn-desktop-titlebar-height)) !important; margin-top: var(--sn-desktop-titlebar-height); }',
sheet.cssRules.length,
)
sheet.insertRule(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { FileItem, PrefKey, PrefValue } from '@standardnotes/models'

export interface SuperConverterServiceInterface {
isValidSuperString(superString: string): boolean
convertSuperStringToOtherFormat: (
superString: string,
toFormat: 'txt' | 'md' | 'html' | 'json' | 'pdf',
config?: {
embedBehavior?: PrefValue[PrefKey.SuperNoteExportEmbedBehavior]
getFileItem?: (id: string) => FileItem | undefined
getFileBase64?: (id: string) => Promise<string | undefined>
pdf?: {
pageSize?: PrefValue[PrefKey.SuperNoteExportPDFPageSize]
}
},
) => Promise<string>
convertOtherFormatToSuperString: (
otherFormatString: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const PrefDefaults = {
[PrefKey.SuperNoteExportFormat]: 'json',
[PrefKey.SuperNoteExportEmbedBehavior]: 'reference',
[PrefKey.SuperNoteExportUseMDFrontmatter]: true,
[PrefKey.SuperNoteExportPDFPageSize]: 'A4',
[PrefKey.SystemViewPreferences]: {},
[PrefKey.AuthenticatorNames]: '',
[PrefKey.ComponentPreferences]: {},
Expand Down
2 changes: 2 additions & 0 deletions packages/models/src/Domain/Syncable/UserPrefs/PrefKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export enum PrefKey {
SuperNoteExportFormat = 'superNoteExportFormat',
SuperNoteExportEmbedBehavior = 'superNoteExportEmbedBehavior',
SuperNoteExportUseMDFrontmatter = 'superNoteExportUseMDFrontmatter',
SuperNoteExportPDFPageSize = 'superNoteExportPDFPageSize',
AuthenticatorNames = 'authenticatorNames',
PaneGesturesEnabled = 'paneGesturesEnabled',
ComponentPreferences = 'componentPreferences',
Expand Down Expand Up @@ -90,6 +91,7 @@ export type PrefValue = {
[PrefKey.SuperNoteExportFormat]: 'json' | 'md' | 'html' | 'pdf'
[PrefKey.SuperNoteExportEmbedBehavior]: 'reference' | 'inline' | 'separate'
[PrefKey.SuperNoteExportUseMDFrontmatter]: boolean
[PrefKey.SuperNoteExportPDFPageSize]: 'A3' | 'A4' | 'LETTER' | 'LEGAL' | 'TABLOID'
[PrefKey.AuthenticatorNames]: string
[PrefKey.PaneGesturesEnabled]: boolean
[PrefKey.ComponentPreferences]: AllComponentPreferences
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ const NotesOptions = ({ notes, closeMenu }: NotesOptionsProps) => {
</>
)}

<ModalOverlay isOpen={showExportSuperModal} close={closeSuperExportModal}>
<ModalOverlay isOpen={showExportSuperModal} close={closeSuperExportModal} className="md:max-w-[25vw]">
<SuperExportModal notes={notes} exportNotes={downloadSelectedItems} close={closeSuperExportModal} />
</ModalOverlay>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import RadioButtonGroup from '../RadioButtonGroup/RadioButtonGroup'
import { useEffect } from 'react'
import Switch from '../Switch/Switch'
import { noteHasEmbeddedFiles } from '@/Utils/NoteExportUtils'
import Dropdown from '../Dropdown/Dropdown'

type Props = {
notes: SNNote[]
Expand All @@ -19,6 +20,7 @@ const SuperExportModal = ({ notes, exportNotes, close }: Props) => {
const superNoteExportFormat = usePreference(PrefKey.SuperNoteExportFormat)
const superNoteExportEmbedBehavior = usePreference(PrefKey.SuperNoteExportEmbedBehavior)
const superNoteExportUseMDFrontmatter = usePreference(PrefKey.SuperNoteExportUseMDFrontmatter)
const superNoteExportPDFPageSize = usePreference(PrefKey.SuperNoteExportPDFPageSize)

useEffect(() => {
if (superNoteExportFormat === 'json' && superNoteExportEmbedBehavior === 'separate') {
Expand Down Expand Up @@ -60,30 +62,59 @@ const SuperExportModal = ({ notes, exportNotes, close }: Props) => {
]}
>
<div className="mb-2">
<div className="mb-3 text-base">We detected your selection includes Super notes.</div>
<div className="mb-1">What format do you want to export them in?</div>
<RadioButtonGroup
items={[
{ label: 'Super (.json)', value: 'json' },
{ label: 'Markdown (.md)', value: 'md' },
{ label: 'HTML', value: 'html' },
{ label: 'PDF', value: 'pdf' },
]}
value={superNoteExportFormat}
onChange={(value) => {
void application.setPreference(
PrefKey.SuperNoteExportFormat,
value as PrefValue[PrefKey.SuperNoteExportFormat],
)
}}
/>
<div className="mb-2 flex items-center justify-between">
<div className="text-base">Choose export format {notes.length > 1 ? 'for Super notes' : ''}</div>
<Dropdown
label="Export format"
items={[
{ label: 'Super (.json)', value: 'json' },
{ label: 'Markdown (.md)', value: 'md' },
{ label: 'HTML', value: 'html' },
{ label: 'PDF', value: 'pdf' },
]}
value={superNoteExportFormat}
onChange={(value) => {
void application.setPreference(
PrefKey.SuperNoteExportFormat,
value as PrefValue[PrefKey.SuperNoteExportFormat],
)
}}
/>
</div>
{superNoteExportFormat === 'md' && (
<div className="mt-2 text-xs text-passive-0">
Note that conversion to Markdown is not lossless. Some features like collapsible blocks and formatting like
superscript/subscript may not be correctly converted.
</div>
)}
</div>
{superNoteExportFormat === 'pdf' && (
<div className="mt-4 flex items-center justify-between">
<div className="text-base">Page size</div>
<Dropdown
label="Page size"
items={
[
{ label: 'A3', value: 'A3' },
{ label: 'A4', value: 'A4' },
{ label: 'Letter', value: 'LETTER' },
{ label: 'Legal', value: 'LEGAL' },
{ label: 'Tabloid', value: 'TABLOID' },
] satisfies {
label: string
value: PrefValue[PrefKey.SuperNoteExportPDFPageSize]
}[]
}
value={superNoteExportPDFPageSize}
onChange={(value) => {
void application.setPreference(
PrefKey.SuperNoteExportPDFPageSize,
value as PrefValue[PrefKey.SuperNoteExportPDFPageSize],
)
}}
/>
</div>
)}
{superNoteExportFormat === 'md' && (
<div className="mt-4">
<Switch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { $isCollapsibleTitleNode } from '../../../Plugins/CollapsiblePlugin/Coll
import { PDFDataNode, PDFWorker } from './PDFWorker'
import { wrap } from 'comlink'
import { getBase64FromBlob } from '@/Utils'
import { PrefKey, PrefValue } from '@standardnotes/snjs'

const styles = StyleSheet.create({
page: {
Expand Down Expand Up @@ -422,15 +423,15 @@ const PDFWorkerComlink = wrap<PDFWorker>(new Worker(new URL('./PDFWorker.tsx', i
/**
* @returns The PDF as a base64 string
*/
export function $generatePDFFromNodes(editor: LexicalEditor) {
export function $generatePDFFromNodes(editor: LexicalEditor, pageSize: PrefValue[PrefKey.SuperNoteExportPDFPageSize]) {
return new Promise<string>((resolve) => {
editor.getEditorState().read(() => {
const root = $getRoot()
const nodes = root.getChildren()

const pdfDataNodes = getPDFDataNodesFromLexicalNodes(nodes)

void PDFWorkerComlink.renderPDF(pdfDataNodes).then((blob) => {
void PDFWorkerComlink.renderPDF(pdfDataNodes, pageSize).then((blob) => {
void getBase64FromBlob(blob).then((base64) => {
resolve(base64)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
TextProps,
SVGProps,
ImageWithSrcProp,
PageProps,
} from '@react-pdf/renderer'
import { expose } from 'comlink'

Expand Down Expand Up @@ -72,10 +73,11 @@ const Node = ({ node }: { node: PDFDataNode }) => {
}
}

const PDFDocument = ({ nodes }: { nodes: PDFDataNode[] }) => {
const PDFDocument = ({ nodes, pageSize }: { nodes: PDFDataNode[]; pageSize: PageProps['size'] }) => {
return (
<Document>
<Page
size={pageSize}
style={{
paddingVertical: 35,
paddingHorizontal: 35,
Expand All @@ -92,8 +94,8 @@ const PDFDocument = ({ nodes }: { nodes: PDFDataNode[] }) => {
)
}

const renderPDF = (nodes: PDFDataNode[]) => {
return pdf(<PDFDocument nodes={nodes} />).toBlob()
const renderPDF = (nodes: PDFDataNode[], pageSize: PageProps['size']) => {
return pdf(<PDFDocument pageSize={pageSize} nodes={nodes} />).toBlob()
}

expose({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
embedBehavior?: PrefValue[PrefKey.SuperNoteExportEmbedBehavior]
getFileItem?: (id: string) => FileItem | undefined
getFileBase64?: (id: string) => Promise<string | undefined>
pdf?: {
pageSize?: PrefValue[PrefKey.SuperNoteExportPDFPageSize]
}
},
): Promise<string> {
if (superString.length === 0) {
Expand Down Expand Up @@ -145,8 +148,8 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
resolve()
break
case 'pdf': {
void import('../Lexical/Utils/PDFExport/PDFExport').then(({ $generatePDFFromNodes }) => {
void $generatePDFFromNodes(this.exportEditor).then((pdf) => {
void import('../Lexical/Utils/PDFExport/PDFExport').then(({ $generatePDFFromNodes }): void => {
void $generatePDFFromNodes(this.exportEditor, config?.pdf?.pageSize || 'A4').then((pdf) => {
content = pdf
resolve()
})
Expand Down
6 changes: 6 additions & 0 deletions packages/web/src/javascripts/Utils/NoteExportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ export const getNoteBlob = async (
}
return await getBase64FromBlob(fileBlob)
},
pdf: {
pageSize: application.getPreference(
PrefKey.SuperNoteExportPDFPageSize,
PrefDefaults[PrefKey.SuperNoteExportPDFPageSize],
),
},
})
const useMDFrontmatter =
format === 'md' &&
Expand Down

0 comments on commit 853fab5

Please sign in to comment.