feat(Nextjs): Font loading in presentation page
This commit is contained in:
parent
e98e0cea50
commit
3ae6a449c1
4 changed files with 40 additions and 29 deletions
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
export const useFontLoader = ( fonts:string[]) => {
|
||||
const injectFonts = (fontUrls: string[]) => {
|
||||
fontUrls.forEach((fontUrl) => {
|
||||
if (!fontUrl) return;
|
||||
let newFontUrl = fontUrl.includes('fonts.googleapis') ? fontUrl : `https://localhost:5000${fontUrl}`;
|
||||
const existingStyle = document.querySelector(`style[data-font-url="${newFontUrl}"]`);
|
||||
if (existingStyle) return;
|
||||
const style = document.createElement("style");
|
||||
style.setAttribute("data-font-url", newFontUrl);
|
||||
style.textContent = `@import url('${newFontUrl}');`;
|
||||
document.head.appendChild(style);
|
||||
});
|
||||
};
|
||||
injectFonts(fonts);
|
||||
};
|
||||
|
|
@ -2,6 +2,7 @@ import { CheckCircle } from "lucide-react";
|
|||
import React from "react";
|
||||
import { LayoutGroup } from "../types/index";
|
||||
import { useLayout } from "../../context/LayoutContext";
|
||||
import { useFontLoader } from "../../hooks/useFontLoader";
|
||||
interface GroupLayoutsProps {
|
||||
group: LayoutGroup;
|
||||
onSelectLayoutGroup: (group: LayoutGroup) => void;
|
||||
|
|
@ -16,26 +17,7 @@ const GroupLayouts: React.FC<GroupLayoutsProps> = ({
|
|||
const { getFullDataByGroup,getCustomTemplateFonts } = useLayout();
|
||||
const layoutGroup = getFullDataByGroup(group.id);
|
||||
const fonts = getCustomTemplateFonts(group.id.split("custom-")[1]);
|
||||
if(fonts){
|
||||
const injectFonts = (fontUrls: string[]) => {
|
||||
console.log('font are applied',fontUrls);
|
||||
fontUrls.forEach((fontUrl) => {
|
||||
if (!fontUrl) return;
|
||||
const existingStyle = document.querySelector(`style[data-font-url="${fontUrl}"]`);
|
||||
if (existingStyle) return;
|
||||
const fileName = fontUrl.split("/").pop() || "CustomFont";
|
||||
const baseName = fileName.replace(/\.[a-zA-Z0-9]+$/, "");
|
||||
const fontFamily = baseName.replace(/[^A-Za-z0-9_-]/g, "_");
|
||||
const ext = (fileName.split(".").pop() || "ttf").toLowerCase();
|
||||
const format = ext === "otf" ? "opentype" : ext === "woff" ? "woff" : ext === "woff2" ? "woff2" : "truetype";
|
||||
const style = document.createElement("style");
|
||||
style.setAttribute("data-font-url", fontUrl);
|
||||
style.textContent = `@font-face { font-family: '${fontFamily}'; src: url('${fontUrl}') format('${format}'); font-display: swap; }`;
|
||||
document.head.appendChild(style);
|
||||
});
|
||||
};
|
||||
injectFonts(fonts);
|
||||
}
|
||||
useFontLoader(fonts || []);
|
||||
return (
|
||||
<div
|
||||
onClick={() => onSelectLayoutGroup(group)}
|
||||
|
|
@ -51,7 +33,7 @@ if(fonts){
|
|||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-3">
|
||||
<div className="mb-3 ">
|
||||
<h6 className="text-base capitalize font-medium text-gray-900 mb-1">
|
||||
{group.name}
|
||||
</h6>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ import { toast } from "sonner";
|
|||
import Announcement from "@/components/Announcement";
|
||||
import { PptxPresentationModel } from "@/types/pptx_models";
|
||||
import HeaderNav from "../../components/HeaderNab";
|
||||
|
||||
import PDFIMAGE from "@/public/pdf.svg";
|
||||
import PPTXIMAGE from "@/public/pptx.svg";
|
||||
import Image from "next/image";
|
||||
|
||||
const Header = ({
|
||||
presentation_id,
|
||||
|
|
@ -137,7 +139,7 @@ const Header = ({
|
|||
onClick={handleExportPdf}
|
||||
variant="ghost"
|
||||
className={`pb-4 border-b rounded-none border-gray-300 w-full flex justify-start text-[#5146E5] ${mobile ? "bg-white py-6 border-none rounded-lg" : ""}`} >
|
||||
<img src="/pdf.svg" alt="pdf export" width={30} height={30} />
|
||||
<Image src={PDFIMAGE} alt="pdf export" width={30} height={30} />
|
||||
Export as PDF
|
||||
</Button>
|
||||
<Button
|
||||
|
|
@ -145,7 +147,7 @@ const Header = ({
|
|||
variant="ghost"
|
||||
className={`w-full flex justify-start text-[#5146E5] ${mobile ? "bg-white py-6" : ""}`}
|
||||
>
|
||||
<img src="/pptx.svg" alt="pptx export" width={30} height={30} />
|
||||
<Image src={PPTXIMAGE} alt="pptx export" width={30} height={30} />
|
||||
Export as PPTX
|
||||
</Button>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
"use client";
|
||||
import React, { useCallback, useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { RootState } from "@/store/store";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
|
|
@ -18,7 +18,8 @@ import {
|
|||
} from "../hooks";
|
||||
import { PresentationPageProps } from "../types";
|
||||
import LoadingState from "./LoadingState";
|
||||
|
||||
import { useLayout } from "../../context/LayoutContext";
|
||||
import { useFontLoader } from "../../hooks/useFontLoader";
|
||||
const PresentationPage: React.FC<PresentationPageProps> = ({
|
||||
presentation_id,
|
||||
}) => {
|
||||
|
|
@ -28,7 +29,8 @@ const PresentationPage: React.FC<PresentationPageProps> = ({
|
|||
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||
const [error, setError] = useState(false);
|
||||
const [isMobilePanelOpen, setIsMobilePanelOpen] = useState(false);
|
||||
|
||||
const {getCustomTemplateFonts} = useLayout();
|
||||
|
||||
const { presentationData, isStreaming } = useSelector(
|
||||
(state: RootState) => state.presentationGeneration
|
||||
);
|
||||
|
|
@ -73,6 +75,15 @@ const PresentationPage: React.FC<PresentationPageProps> = ({
|
|||
handleSlideChange(newSlide, presentationData);
|
||||
};
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if(!loading && !isStreaming && presentationData?.slides && presentationData?.slides.length > 0){
|
||||
const presentation_id = presentationData?.slides[0].layout.split(":")[0].split("custom-")[1];
|
||||
const fonts = getCustomTemplateFonts(presentation_id);
|
||||
|
||||
useFontLoader(fonts || []);
|
||||
}
|
||||
}, [presentationData,loading,isStreaming]);
|
||||
// Presentation Mode View
|
||||
if (isPresentMode) {
|
||||
return (
|
||||
|
|
@ -120,13 +131,13 @@ const PresentationPage: React.FC<PresentationPageProps> = ({
|
|||
}}
|
||||
className="flex flex-1 relative pt-6"
|
||||
>
|
||||
{!isStreaming &&<SidePanel
|
||||
<SidePanel
|
||||
selectedSlide={selectedSlide}
|
||||
onSlideClick={handleSlideClick}
|
||||
loading={loading}
|
||||
isMobilePanelOpen={isMobilePanelOpen}
|
||||
setIsMobilePanelOpen={setIsMobilePanelOpen}
|
||||
/>}
|
||||
/>
|
||||
|
||||
<div className="flex-1 h-[calc(100vh-100px)] overflow-y-auto">
|
||||
<div
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue