mirror of
https://github.com/zadam/trilium.git
synced 2025-10-21 07:38:53 +02:00
feat(client/print): render presentation without shadow DOM
This commit is contained in:
parent
e374b31a1c
commit
f6d7ecab40
@ -138,7 +138,7 @@ export default class DesktopLayout {
|
|||||||
.child(new PromotedAttributesWidget())
|
.child(new PromotedAttributesWidget())
|
||||||
.child(<SqlTableSchemas />)
|
.child(<SqlTableSchemas />)
|
||||||
.child(new NoteDetailWidget())
|
.child(new NoteDetailWidget())
|
||||||
.child(<NoteList />)
|
.child(<NoteList media="screen" />)
|
||||||
.child(<SearchResult />)
|
.child(<SearchResult />)
|
||||||
.child(<SqlResults />)
|
.child(<SqlResults />)
|
||||||
.child(<ScrollPadding />)
|
.child(<ScrollPadding />)
|
||||||
|
@ -66,6 +66,6 @@ export function applyModals(rootContainer: RootContainer) {
|
|||||||
.child(<PopupEditorFormattingToolbar />)
|
.child(<PopupEditorFormattingToolbar />)
|
||||||
.child(new PromotedAttributesWidget())
|
.child(new PromotedAttributesWidget())
|
||||||
.child(new NoteDetailWidget())
|
.child(new NoteDetailWidget())
|
||||||
.child(<NoteList displayOnlyCollections />))
|
.child(<NoteList media="screen" displayOnlyCollections />))
|
||||||
.child(<CallToActionDialog />);
|
.child(<CallToActionDialog />);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ export default class MobileLayout {
|
|||||||
.filling()
|
.filling()
|
||||||
.contentSized()
|
.contentSized()
|
||||||
.child(new NoteDetailWidget())
|
.child(new NoteDetailWidget())
|
||||||
.child(<NoteList />)
|
.child(<NoteList media="screen" />)
|
||||||
.child(<FilePropertiesWrapper />)
|
.child(<FilePropertiesWrapper />)
|
||||||
)
|
)
|
||||||
.child(<MobileEditorToolbar />)
|
.child(<MobileEditorToolbar />)
|
||||||
|
@ -32,6 +32,7 @@ function handleCollection(note: FNote) {
|
|||||||
notePath={note.getBestNotePath().join("/")}
|
notePath={note.getBestNotePath().join("/")}
|
||||||
ntxId="print"
|
ntxId="print"
|
||||||
highlightedTokens={null}
|
highlightedTokens={null}
|
||||||
|
media="print"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { allViewTypes, ViewModeProps, ViewTypeOptions } from "./interface";
|
import { allViewTypes, ViewModeMedia, ViewModeProps, ViewTypeOptions } from "./interface";
|
||||||
import { useNoteContext, useNoteLabel, useNoteLabelBoolean, useTriliumEvent } from "../react/hooks";
|
import { useNoteContext, useNoteLabel, useNoteLabelBoolean, useTriliumEvent } from "../react/hooks";
|
||||||
import FNote from "../../entities/fnote";
|
import FNote from "../../entities/fnote";
|
||||||
import "./NoteList.css";
|
import "./NoteList.css";
|
||||||
@ -22,9 +22,10 @@ interface NoteListProps {
|
|||||||
displayOnlyCollections?: boolean;
|
displayOnlyCollections?: boolean;
|
||||||
isEnabled: boolean;
|
isEnabled: boolean;
|
||||||
ntxId: string | null | undefined;
|
ntxId: string | null | undefined;
|
||||||
|
media: ViewModeMedia;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function NoteList<T extends object>(props: Pick<NoteListProps, "displayOnlyCollections">) {
|
export default function NoteList<T extends object>(props: Pick<NoteListProps, "displayOnlyCollections" | "media">) {
|
||||||
const { note, noteContext, notePath, ntxId } = useNoteContext();
|
const { note, noteContext, notePath, ntxId } = useNoteContext();
|
||||||
const isEnabled = noteContext?.hasNoteList();
|
const isEnabled = noteContext?.hasNoteList();
|
||||||
return <CustomNoteList note={note} isEnabled={!!isEnabled} notePath={notePath} ntxId={ntxId} {...props} />
|
return <CustomNoteList note={note} isEnabled={!!isEnabled} notePath={notePath} ntxId={ntxId} {...props} />
|
||||||
@ -34,7 +35,7 @@ export function SearchNoteList<T extends object>(props: Omit<NoteListProps, "isE
|
|||||||
return <CustomNoteList {...props} isEnabled={true} />
|
return <CustomNoteList {...props} isEnabled={true} />
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CustomNoteList<T extends object>({ note, isEnabled: shouldEnable, notePath, highlightedTokens, displayOnlyCollections, ntxId }: NoteListProps) {
|
export function CustomNoteList<T extends object>({ note, isEnabled: shouldEnable, notePath, highlightedTokens, displayOnlyCollections, ntxId, ...restProps }: NoteListProps) {
|
||||||
const widgetRef = useRef<HTMLDivElement>(null);
|
const widgetRef = useRef<HTMLDivElement>(null);
|
||||||
const viewType = useNoteViewType(note);
|
const viewType = useNoteViewType(note);
|
||||||
const noteIds = useNoteIds(note, viewType, ntxId);
|
const noteIds = useNoteIds(note, viewType, ntxId);
|
||||||
@ -76,7 +77,8 @@ export function CustomNoteList<T extends object>({ note, isEnabled: shouldEnable
|
|||||||
note, noteIds, notePath,
|
note, noteIds, notePath,
|
||||||
highlightedTokens,
|
highlightedTokens,
|
||||||
viewConfig: viewModeConfig[0],
|
viewConfig: viewModeConfig[0],
|
||||||
saveConfig: viewModeConfig[1]
|
saveConfig: viewModeConfig[1],
|
||||||
|
...restProps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ import FNote from "../../entities/fnote";
|
|||||||
export const allViewTypes = ["list", "grid", "calendar", "table", "geoMap", "board", "presentation"] as const;
|
export const allViewTypes = ["list", "grid", "calendar", "table", "geoMap", "board", "presentation"] as const;
|
||||||
export type ViewTypeOptions = typeof allViewTypes[number];
|
export type ViewTypeOptions = typeof allViewTypes[number];
|
||||||
|
|
||||||
|
export type ViewModeMedia = "screen" | "print";
|
||||||
|
|
||||||
export interface ViewModeProps<T extends object> {
|
export interface ViewModeProps<T extends object> {
|
||||||
note: FNote;
|
note: FNote;
|
||||||
notePath: string;
|
notePath: string;
|
||||||
@ -13,4 +15,5 @@ export interface ViewModeProps<T extends object> {
|
|||||||
highlightedTokens: string[] | null | undefined;
|
highlightedTokens: string[] | null | undefined;
|
||||||
viewConfig: T | undefined;
|
viewConfig: T | undefined;
|
||||||
saveConfig(newConfig: T): void;
|
saveConfig(newConfig: T): void;
|
||||||
|
media: ViewModeMedia;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import { t } from "../../../services/i18n";
|
|||||||
import { DEFAULT_THEME, loadPresentationTheme } from "./themes";
|
import { DEFAULT_THEME, loadPresentationTheme } from "./themes";
|
||||||
import FNote from "../../../entities/fnote";
|
import FNote from "../../../entities/fnote";
|
||||||
|
|
||||||
export default function PresentationView({ note, noteIds }: ViewModeProps<{}>) {
|
export default function PresentationView({ note, noteIds, media }: ViewModeProps<{}>) {
|
||||||
const [ presentation, setPresentation ] = useState<PresentationModel>();
|
const [ presentation, setPresentation ] = useState<PresentationModel>();
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const [ api, setApi ] = useState<Reveal.Api>();
|
const [ api, setApi ] = useState<Reveal.Api>();
|
||||||
@ -33,18 +33,28 @@ export default function PresentationView({ note, noteIds }: ViewModeProps<{}>) {
|
|||||||
|
|
||||||
useLayoutEffect(refresh, [ note, noteIds ]);
|
useLayoutEffect(refresh, [ note, noteIds ]);
|
||||||
|
|
||||||
return presentation && stylesheets && (
|
if (!presentation || !stylesheets) return;
|
||||||
|
const content = (
|
||||||
<>
|
<>
|
||||||
<ShadowDom
|
{stylesheets.map(stylesheet => <style>{stylesheet}</style>)}
|
||||||
className="presentation-container"
|
<Presentation presentation={presentation} setApi={setApi} />
|
||||||
containerRef={containerRef}
|
|
||||||
>
|
|
||||||
{stylesheets.map(stylesheet => <style>{stylesheet}</style>)}
|
|
||||||
<Presentation presentation={presentation} setApi={setApi} />
|
|
||||||
</ShadowDom>
|
|
||||||
<ButtonOverlay containerRef={containerRef} api={api} />
|
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
|
|
||||||
|
if (media === "screen") {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ShadowDom
|
||||||
|
className="presentation-container"
|
||||||
|
containerRef={containerRef}
|
||||||
|
>{content}</ShadowDom>
|
||||||
|
<ButtonOverlay containerRef={containerRef} api={api} />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// Shadow DOM doesn't work well with Reveal.js's PDF printing mechanism.
|
||||||
|
return content;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function usePresentationStylesheets(note: FNote) {
|
function usePresentationStylesheets(note: FNote) {
|
||||||
@ -128,6 +138,7 @@ function Presentation({ presentation, setApi } : { presentation: PresentationMod
|
|||||||
const api = new Reveal(containerRef.current, {
|
const api = new Reveal(containerRef.current, {
|
||||||
transition: "slide",
|
transition: "slide",
|
||||||
embedded: true,
|
embedded: true,
|
||||||
|
pdfMaxPagesPerSlide: 1,
|
||||||
keyboardCondition(event) {
|
keyboardCondition(event) {
|
||||||
// Full-screen requests sometimes fail, we rely on the UI button instead.
|
// Full-screen requests sometimes fail, we rely on the UI button instead.
|
||||||
if (event.key === "f") {
|
if (event.key === "f") {
|
||||||
|
@ -54,6 +54,7 @@ export default function SearchResult() {
|
|||||||
|
|
||||||
{state === SearchResultState.GOT_RESULTS && (
|
{state === SearchResultState.GOT_RESULTS && (
|
||||||
<SearchNoteList
|
<SearchNoteList
|
||||||
|
media="screen"
|
||||||
note={note}
|
note={note}
|
||||||
notePath={notePath}
|
notePath={notePath}
|
||||||
highlightedTokens={highlightedTokens}
|
highlightedTokens={highlightedTokens}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user