fix: include logo in screenshot, fix screenshots on small/zoomed windows (#579)
* fix: include logo in screenshot * fix: screenshots on small/zoomed windows, screenshots with no async/other --------- Co-authored-by: Razboy20 <razboy20@gmail.com>
This commit is contained in:
@@ -33,6 +33,8 @@ import CalendarFooter from './CalendarFooter';
|
||||
*/
|
||||
export default function Calendar(): ReactNode {
|
||||
const { courseCells, activeSchedule } = useFlattenedCourseSchedule();
|
||||
const asyncCourseCells = courseCells.filter(block => block.async);
|
||||
const displayBottomBar = asyncCourseCells && asyncCourseCells.length > 0;
|
||||
|
||||
const [course, setCourse] = useState<Course | null>(useCourseFromUrl());
|
||||
|
||||
@@ -85,7 +87,7 @@ export default function Calendar(): ReactNode {
|
||||
return (
|
||||
<CalendarContext.Provider value>
|
||||
<div className='h-full w-full flex flex-col'>
|
||||
<div className='h-screen flex overflow-auto'>
|
||||
<div className='h-screen flex overflow-auto screenshot:calendar-target'>
|
||||
<div
|
||||
className={clsx(
|
||||
'py-spacing-6 relative h-full min-h-screen w-full flex flex-none flex-col justify-between overflow-clip whitespace-nowrap border-r border-ut-offwhite/50 shadow-[2px_0_10px,rgba(214_210_196_/_.1)] motion-safe:duration-300 motion-safe:ease-out-expo motion-safe:transition-[max-width] screenshot:hidden',
|
||||
@@ -169,7 +171,11 @@ export default function Calendar(): ReactNode {
|
||||
setShowSidebar(!showSidebar);
|
||||
}}
|
||||
/>
|
||||
<div className='min-h-2xl min-w-5xl flex-grow gap-0 pl-spacing-3 screenshot:min-h-xl'>
|
||||
<div
|
||||
className={clsx('min-h-2xl min-w-5xl flex-grow gap-0 pl-spacing-3 screenshot:min-h-xl', {
|
||||
'screenshot:flex-grow-0': displayBottomBar, // html-to-image seems to have a bug with flex-grow
|
||||
})}
|
||||
>
|
||||
<CalendarGrid courseCells={courseCells} setCourse={setCourse} />
|
||||
</div>
|
||||
<CalendarBottomBar courseCells={courseCells} setCourse={setCourse} />
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Button } from '@views/components/common/Button';
|
||||
import DialogProvider from '@views/components/common/DialogProvider/DialogProvider';
|
||||
import Divider from '@views/components/common/Divider';
|
||||
import { ExtensionRootWrapper, styleResetClass } from '@views/components/common/ExtensionRoot/ExtensionRoot';
|
||||
import { LargeLogo } from '@views/components/common/LogoIcon';
|
||||
import ScheduleTotalHoursAndCourses from '@views/components/common/ScheduleTotalHoursAndCourses';
|
||||
import useSchedules from '@views/hooks/useSchedules';
|
||||
import clsx from 'clsx';
|
||||
@@ -39,6 +40,9 @@ export default function CalendarHeader({ sidebarOpen, onSidebarToggle }: Calenda
|
||||
/>
|
||||
)}
|
||||
|
||||
<LargeLogo className='hidden! screenshot:flex!' />
|
||||
<Divider className='self-center hidden! screenshot:block!' size='2.5rem' orientation='vertical' />
|
||||
|
||||
<div className='min-w-[11.5rem] screenshot:transform-origin-left screenshot:scale-120'>
|
||||
<ScheduleTotalHoursAndCourses
|
||||
scheduleName={activeSchedule.name}
|
||||
|
||||
@@ -266,31 +266,38 @@ export const saveAsCal = async () => {
|
||||
* @param calendarRef - The reference to the calendar component.
|
||||
*/
|
||||
export const saveCalAsPng = () => {
|
||||
const WIDTH_PX = 1165;
|
||||
const HEIGHT_PX = 754;
|
||||
const SCALE = 2;
|
||||
|
||||
const rootNode = document.createElement('div');
|
||||
rootNode.style.backgroundColor = 'white';
|
||||
rootNode.style.position = 'fixed';
|
||||
rootNode.style.zIndex = '1000';
|
||||
rootNode.style.top = '-10000px';
|
||||
rootNode.style.left = '-10000px';
|
||||
rootNode.style.width = '1165px';
|
||||
rootNode.style.height = '754px';
|
||||
rootNode.style.width = `${WIDTH_PX}px`;
|
||||
rootNode.style.height = `${HEIGHT_PX}px`;
|
||||
document.body.appendChild(rootNode);
|
||||
|
||||
const clonedNode = document.querySelector('#root')!.cloneNode(true) as HTMLDivElement;
|
||||
clonedNode.style.backgroundColor = 'white';
|
||||
(clonedNode.firstChild as HTMLDivElement).classList.add('screenshot-in-progress');
|
||||
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
requestAnimationFrame(async () => {
|
||||
rootNode.appendChild(clonedNode);
|
||||
const calendarTarget = clonedNode.querySelector('.screenshot\\:calendar-target') as HTMLDivElement;
|
||||
calendarTarget.style.width = `${WIDTH_PX}px`;
|
||||
calendarTarget.style.height = `${HEIGHT_PX}px`;
|
||||
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
rootNode.appendChild(clonedNode);
|
||||
requestAnimationFrame(async () => {
|
||||
try {
|
||||
const screenshotBlob = await toBlob(clonedNode, {
|
||||
cacheBust: true,
|
||||
canvasWidth: 1165 * 2,
|
||||
canvasHeight: 754 * 2,
|
||||
canvasWidth: WIDTH_PX * SCALE,
|
||||
canvasHeight: HEIGHT_PX * SCALE,
|
||||
skipAutoScale: true,
|
||||
pixelRatio: 2,
|
||||
pixelRatio: SCALE,
|
||||
});
|
||||
|
||||
if (!screenshotBlob) {
|
||||
|
||||
Reference in New Issue
Block a user