Introduce a footer-triggered Version History drawer with categorized release notes, hardcoded release data, and semver tracking at v0.3.0. Also ships blog blockquote/table styling, site-wide typography, home page image updates, header refinements, and related bug fixes. Co-authored-by: Cursor <cursoragent@cursor.com>
91 lines
2.6 KiB
TypeScript
91 lines
2.6 KiB
TypeScript
import fs from "fs";
|
|
import path from "path";
|
|
|
|
export type LocalImage = {
|
|
src: string;
|
|
width: number;
|
|
height: number;
|
|
};
|
|
|
|
function readJpegSize(buffer: Buffer): { width: number; height: number } {
|
|
let i = 2;
|
|
while (i < buffer.length) {
|
|
if (buffer[i] !== 0xff) break;
|
|
const marker = buffer[i + 1];
|
|
if (marker === 0xc0 || marker === 0xc1 || marker === 0xc2) {
|
|
return {
|
|
height: buffer.readUInt16BE(i + 5),
|
|
width: buffer.readUInt16BE(i + 7),
|
|
};
|
|
}
|
|
i += 2 + buffer.readUInt16BE(i + 2);
|
|
}
|
|
throw new Error("Could not read JPEG dimensions");
|
|
}
|
|
|
|
function localImage(publicPath: string, publicUrl?: string): LocalImage {
|
|
const filePath = path.join(process.cwd(), "public", publicPath.replace(/^\//, ""));
|
|
const buffer = fs.readFileSync(filePath);
|
|
const { width, height } = readJpegSize(buffer);
|
|
|
|
return {
|
|
src: publicUrl ?? publicPath,
|
|
width,
|
|
height,
|
|
};
|
|
}
|
|
|
|
function sectionImage(filename: string): LocalImage {
|
|
return localImage(
|
|
`/assets/main-pic/4section/${filename}`,
|
|
`/assets/main-pic/4section/${encodeURIComponent(filename)}`,
|
|
);
|
|
}
|
|
|
|
export type FeatureImageKey = "item-1" | "item-2" | "item-3" | "item-4";
|
|
|
|
export type FeatureImageSet = Record<
|
|
FeatureImageKey,
|
|
{
|
|
image: LocalImage;
|
|
imageDark: LocalImage;
|
|
alt: string;
|
|
}
|
|
>;
|
|
|
|
export function getHomeImages() {
|
|
return {
|
|
hero: {
|
|
backgroundDark: localImage("/assets/main-pic/1dark.jpg"),
|
|
main: localImage("/assets/main-pic/1.jpg"),
|
|
mainDark: localImage("/assets/main-pic/1dark.jpg"),
|
|
},
|
|
features: {
|
|
"item-1": {
|
|
image: sectionImage("Systems Integration.jpg"),
|
|
imageDark: sectionImage("Systems Integration-dark.jpg"),
|
|
alt: "یکپارچهسازی سیستمها",
|
|
},
|
|
"item-2": {
|
|
image: sectionImage("Powerful Management panels.jpg"),
|
|
imageDark: sectionImage("Powerful Management panels-dark.jpg"),
|
|
alt: "پنلهای مدیریتی قدرتمند",
|
|
},
|
|
"item-3": {
|
|
image: sectionImage("Interaction with Social Networks.jpg"),
|
|
imageDark: sectionImage("Interaction with Social Networks_dark.jpg"),
|
|
alt: "تعامل با شبکههای اجتماعی",
|
|
},
|
|
"item-4": {
|
|
image: sectionImage("Process Automation.jpg"),
|
|
imageDark: sectionImage("Process Automation-dark.jpg"),
|
|
alt: "اتوماسیون فرآیندها",
|
|
},
|
|
} satisfies FeatureImageSet,
|
|
ecosystem: {
|
|
light: localImage("/assets/main-pic/intelligent-workflow-control-center.jpg"),
|
|
dark: localImage("/assets/main-pic/intelligent-workflow-control-center-dark.jpg"),
|
|
},
|
|
};
|
|
}
|