mirror of
https://github.com/zadam/trilium.git
synced 2025-10-19 22:58:52 +02:00
feat(collection/presentation): load themes
This commit is contained in:
parent
8a86fdcd43
commit
7c2c89d4e2
@ -2,7 +2,6 @@ import { ViewModeProps } from "../interface";
|
||||
import { useEffect, useLayoutEffect, useRef, useState } from "preact/hooks";
|
||||
import Reveal from "reveal.js";
|
||||
import slideBaseStylesheet from "reveal.js/dist/reveal.css?raw";
|
||||
import slideThemeStylesheet from "reveal.js/dist/theme/black.css?raw";
|
||||
import slideCustomStylesheet from "./slidejs.css?raw";
|
||||
import { buildPresentationModel, PresentationModel, PresentationSlideBaseModel } from "./model";
|
||||
import ShadowDom from "../../react/ShadowDom";
|
||||
@ -10,19 +9,16 @@ import ActionButton from "../../react/ActionButton";
|
||||
import "./index.css";
|
||||
import { RefObject } from "preact";
|
||||
import { openInCurrentNoteContext } from "../../../components/note_context";
|
||||
import { useTriliumEvent } from "../../react/hooks";
|
||||
import { useNoteLabelWithDefault, useTriliumEvent } from "../../react/hooks";
|
||||
import { t } from "../../../services/i18n";
|
||||
|
||||
const stylesheets = [
|
||||
slideBaseStylesheet,
|
||||
slideThemeStylesheet,
|
||||
slideCustomStylesheet
|
||||
].map(stylesheet => stylesheet.replace(/:root/g, ":host"));
|
||||
import { DEFAULT_THEME, loadPresentationTheme } from "./themes";
|
||||
import FNote from "../../../entities/fnote";
|
||||
|
||||
export default function PresentationView({ note, noteIds }: ViewModeProps<{}>) {
|
||||
const [ presentation, setPresentation ] = useState<PresentationModel>();
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [ api, setApi ] = useState<Reveal.Api>();
|
||||
const stylesheets = usePresentationStylesheets(note);
|
||||
|
||||
function refresh() {
|
||||
buildPresentationModel(note).then(setPresentation);
|
||||
@ -36,7 +32,7 @@ export default function PresentationView({ note, noteIds }: ViewModeProps<{}>) {
|
||||
|
||||
useLayoutEffect(refresh, [ note, noteIds ]);
|
||||
|
||||
return presentation && (
|
||||
return presentation && stylesheets && (
|
||||
<>
|
||||
<ShadowDom
|
||||
className="presentation-container"
|
||||
@ -50,6 +46,23 @@ export default function PresentationView({ note, noteIds }: ViewModeProps<{}>) {
|
||||
)
|
||||
}
|
||||
|
||||
function usePresentationStylesheets(note: FNote) {
|
||||
const [ themeName ] = useNoteLabelWithDefault(note, "presentation:theme", DEFAULT_THEME);
|
||||
const [ stylesheets, setStylesheets ] = useState<string[]>();
|
||||
|
||||
useLayoutEffect(() => {
|
||||
loadPresentationTheme(themeName).then((themeStylesheet) => {
|
||||
setStylesheets([
|
||||
slideBaseStylesheet,
|
||||
themeStylesheet,
|
||||
slideCustomStylesheet
|
||||
].map(stylesheet => stylesheet.replace(/:root/g, ":host")));
|
||||
});
|
||||
}, [ themeName ]);
|
||||
|
||||
return stylesheets;
|
||||
}
|
||||
|
||||
function ButtonOverlay({ containerRef, api }: { containerRef: RefObject<HTMLDivElement>, api: Reveal.Api | undefined }) {
|
||||
const [ isOverviewActive, setIsOverviewActive ] = useState(false);
|
||||
useEffect(() => {
|
||||
|
@ -0,0 +1,10 @@
|
||||
import { it, describe } from "vitest";
|
||||
import { getPresentationThemes, loadPresentationTheme } from "./themes";
|
||||
|
||||
describe("Presentation themes", () => {
|
||||
it("can load all themes", async () => {
|
||||
const themes = getPresentationThemes();
|
||||
|
||||
await Promise.all(themes.map(theme => loadPresentationTheme(theme.id)));
|
||||
});
|
||||
});
|
@ -1,3 +1,5 @@
|
||||
export const DEFAULT_THEME = "white";
|
||||
|
||||
interface ThemeDefinition {
|
||||
name: string;
|
||||
loadTheme: () => Promise<typeof import("*.css?raw")>;
|
||||
@ -10,39 +12,39 @@ const themes: Record<string, ThemeDefinition> = {
|
||||
},
|
||||
white: {
|
||||
name: "White",
|
||||
loadTheme: () => import("reveal.js/dist/theme/black.css?raw")
|
||||
loadTheme: () => import("reveal.js/dist/theme/white.css?raw")
|
||||
},
|
||||
beige: {
|
||||
name: "Beige",
|
||||
loadTheme: () => import("reveal.js/dist/theme/black.css?raw")
|
||||
loadTheme: () => import("reveal.js/dist/theme/beige.css?raw")
|
||||
},
|
||||
serif: {
|
||||
name: "Serif",
|
||||
loadTheme: () => import("reveal.js/dist/theme/black.css?raw")
|
||||
loadTheme: () => import("reveal.js/dist/theme/serif.css?raw")
|
||||
},
|
||||
simple: {
|
||||
name: "Simple",
|
||||
loadTheme: () => import("reveal.js/dist/theme/black.css?raw")
|
||||
loadTheme: () => import("reveal.js/dist/theme/simple.css?raw")
|
||||
},
|
||||
solarized: {
|
||||
name: "Solarized",
|
||||
loadTheme: () => import("reveal.js/dist/theme/black.css?raw")
|
||||
loadTheme: () => import("reveal.js/dist/theme/solarized.css?raw")
|
||||
},
|
||||
moon: {
|
||||
name: "Moon",
|
||||
loadTheme: () => import("reveal.js/dist/theme/black.css?raw")
|
||||
loadTheme: () => import("reveal.js/dist/theme/moon.css?raw")
|
||||
},
|
||||
dracula: {
|
||||
name: "Dracula",
|
||||
loadTheme: () => import("reveal.js/dist/theme/black.css?raw")
|
||||
loadTheme: () => import("reveal.js/dist/theme/dracula.css?raw")
|
||||
},
|
||||
sky: {
|
||||
name: "Sky",
|
||||
loadTheme: () => import("reveal.js/dist/theme/black.css?raw")
|
||||
loadTheme: () => import("reveal.js/dist/theme/sky.css?raw")
|
||||
},
|
||||
blood: {
|
||||
name: "Blood",
|
||||
loadTheme: () => import("reveal.js/dist/theme/black.css?raw")
|
||||
loadTheme: () => import("reveal.js/dist/theme/blood.css?raw")
|
||||
}
|
||||
} as const;
|
||||
|
||||
@ -54,8 +56,8 @@ export function getPresentationThemes() {
|
||||
}
|
||||
|
||||
export async function loadPresentationTheme(name: keyof typeof themes) {
|
||||
const theme = themes[name];
|
||||
if (!theme) return;
|
||||
let theme = themes[name];
|
||||
if (!theme) theme = themes[DEFAULT_THEME];
|
||||
|
||||
return (await theme.loadTheme()).default;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user