Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static Images #654

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions api/img/png.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { VercelApiHandler } from "@vercel/node";
import { supabase } from "../_lib/_supabase";
import { getPng } from "static";
import { parse, toCytoscapeElements } from "graph-selector";

/**
NEXT STEP
- get cytoscape installed either her or in a third package and render anything
*/

// This handler is going to produce a static png image of a given id
const handler: VercelApiHandler = async (req, res) => {
// get id from the query
const id = req.query.id;

if (!id) {
res.status(400).send("id is required");
return;
}

// loop up code in database
const chart = await supabase
.from("user_charts")
.select("*")
.eq("id", id)
.single();

if (!isValid(chart)) {
res.status(404).send("Chart not found");
return;
}

const { content, meta } = parseChart(chart.data.chart);
console.log(meta);
const graph = parse(content);
const elements = toCytoscapeElements(graph);

const base64Str = await getPng({ elements });

res.setHeader("Content-Type", "image/png");
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
res.send(Buffer.from(base64Str, "base64"));
};

export default handler;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isValid(project: any): project is { data: { chart: string } } {
return (
typeof project === "object" &&
project !== null &&
typeof project?.data === "object" &&
project?.data !== null &&
typeof project?.data?.chart === "string"
);
}

/**
* Given a chart string, parses it into
*/
function parseChart(chart: string) {
const [content, metaStr] = chart.split("=====");
const meta = JSON.parse(metaStr);
return {
content,
meta,
};
}
3 changes: 2 additions & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"shared": "workspace:*",
"stripe": "^11.11.0",
"zod": "^3.22.4",
"zod-to-json-schema": "^3.22.3"
"zod-to-json-schema": "^3.22.3",
"static": "workspace:*"
},
"devDependencies": {
"@swc/jest": "^0.2.24",
Expand Down
Binary file added app/public/templates/template21.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion app/src/components/Graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ import { getNodePositionsFromCy } from "./getNodePositionsFromCy";
import styles from "./Graph.module.css";
import { GRAPH_CONTEXT_MENU_ID, GraphContextMenu } from "./GraphContextMenu";
import classNames from "classnames";
import { getThemeEditor, toTheme, useBackground } from "../lib/toTheme";
import { getThemeEditor, toTheme } from "../lib/toTheme";
import equal from "fast-deep-equal";
import { useBackground } from "../lib/toThemeDynamic";
declare global {
interface Window {
__cy?: cytoscape.Core;
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/LoadTemplateDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import classNames from "classnames";
import { useDoc } from "../lib/useDoc";
import { prepareChart } from "../lib/prepareChart/prepareChart";
import { mountGraph, unmountGraph } from "../lib/useUnmountStore";
import { FFTheme } from "../lib/FFTheme";
import type { FFTheme } from "shared";
import { getDefaultText } from "../lib/getDefaultText";

/**
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/Tabs/ThemeTab.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { createControls } from "formulaic";
import { updateThemeEditor, useThemeEditor } from "../../lib/toTheme";
import {
import type {
FFTheme,
Shape,
CurveStyle,
ArrowShape,
Direction,
LayoutName,
} from "../../lib/FFTheme";
} from "shared";
import { ReactNode } from "react";

import classNames from "classnames";
Expand All @@ -33,6 +32,7 @@ import {
TextAa,
} from "phosphor-react";
import { useGraphStore } from "../../lib/useGraphStore";
import { updateThemeEditor, useThemeEditor } from "../../lib/toThemeDynamic";

const createForm = createControls({
select,
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/downloads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { saveAs } from "file-saver";

import { UNAUTH_IMG_SCALE } from "../lib/constants";
import { cytoscape } from "../lib/cytoscape";
import { getBackground } from "../lib/toTheme";
import { getBackground } from "../lib/toThemeDynamic";

// padding, gets divided in half
const PADDING = 60;
Expand Down
2 changes: 1 addition & 1 deletion app/src/lib/prepareChart/prepareChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { getStyleStringFromMeta, preprocessStyle } from "../preprocessStyle";
import { Details, useDoc } from "../useDoc";
import { cytoscapeStyle, theme } from "../templates/default-template";
import { FFTheme } from "../FFTheme";
import type { FFTheme } from "shared";

/**
* Ensures the document loaded externally or from local storage
Expand Down
2 changes: 1 addition & 1 deletion app/src/lib/preprocessStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { create } from "zustand";
import { devtools } from "zustand/middleware";

import { resetGraph } from "./useUnmountStore";
import { FFTheme } from "./FFTheme";
import type { FFTheme } from "shared";
import { toTheme } from "./toTheme";

(async () => {
Expand Down
2 changes: 1 addition & 1 deletion app/src/lib/templates/code-flow-template.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FFTheme } from "../FFTheme";
import type { FFTheme } from "shared";

export const content = `
Database
Expand Down
4 changes: 2 additions & 2 deletions app/src/lib/templates/default-template.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FFTheme } from "../FFTheme";
import type { FFTheme } from "shared";

export const content = `
Begin Typing
Expand Down Expand Up @@ -39,4 +39,4 @@ export const theme: FFTheme = {
};

export const cytoscapeStyle =
"$color: #31405b;\n$red: #e63946;\n$orange: #f4a261;\n$yellow: #f1fa3b;\n$green: #2a9d8f;\n$blue: #606ef6;\n$purple: #6d4a7c;\n$grey: #f2eded;\n\n:childless {\n font-weight: 500;\n}\n\n/** Start */\n:childless[in_degree < 1][out_degree > 0] {\n border-width: 0;\n shape: roundrectangle;\n background-color: $green;\n color: white;\n}\n\n/** Terminal */\n:childless[out_degree < 1][in_degree > 0] {\n border-width: 0;\n shape: roundrectangle;\n background-color: $red;\n color: white;\n}\n\n/** Branching */\n:childless[in_degree > 0][in_degree < 2][out_degree > 1] {\n shape: diamond;\n background-color: $blue;\n color: white;\n height: $width;\n border-width: 0;\n text-margin-y: 2;\n}\n\n/** Merging **/\n:childless[in_degree > 1][out_degree > 0][out_degree < 2] {\n}\n\n:childless.color_red {\n background-color: $red;\n color: white;\n}\n:childless.color_orange {\n background-color: $orange;\n color: white;\n}\n:childless.color_yellow {\n background-color: $yellow;\n}\n:childless.color_green {\n background-color: $green;\n color: white;\n}\n:childless.color_blue {\n background-color: $blue;\n color: white;\n}\n:childless.color_purple {\n background-color: $purple;\n color: white;\n}\n:childless.color_grey {\n background-color: $grey;\n}\n\n:parent.color_white {\n background-color: white;\n}\n:parent.color_grey {\n background-color: $grey;\n}";
"$color: #31405b;\n$red: #e63946;\n$orange: #f4a261;\n$yellow: #f1fa3b;\n$green: #2a9d8f;\n$blue: #606ef6;\n$purple: #6d4a7c;\n$grey: #f2eded;\n\n:childless {\n font-weight: 500;\n}\n\n/** Start - uncomment to use\n:childless[in_degree < 1][out_degree > 0] {\n border-width: 0;\n shape: roundrectangle;\n background-color: $green;\n color: white;\n}\n*/\n\n/** Terminal - uncomment to use\n:childless[out_degree < 1][in_degree > 0] {\n border-width: 0;\n shape: roundrectangle;\n background-color: $red;\n color: white;\n}\n*/\n\n/** Branching - uncomment to use\n:childless[in_degree > 0][in_degree < 2][out_degree > 1] {\n shape: diamond;\n background-color: $blue;\n color: white;\n height: $width;\n border-width: 0;\n text-margin-y: 2;\n}\n*/\n\n/** Merging **/\n:childless[in_degree > 1][out_degree > 0][out_degree < 2] {\n}\n\n:childless.color_red {\n background-color: $red;\n color: white;\n}\n:childless.color_orange {\n background-color: $orange;\n color: white;\n}\n:childless.color_yellow {\n background-color: $yellow;\n}\n:childless.color_green {\n background-color: $green;\n color: white;\n}\n:childless.color_blue {\n background-color: $blue;\n color: white;\n}\n:childless.color_purple {\n background-color: $purple;\n color: white;\n}\n:childless.color_grey {\n background-color: $grey;\n}\n\n:parent.color_white {\n background-color: white;\n}\n:parent.color_grey {\n background-color: $grey;\n}";
2 changes: 1 addition & 1 deletion app/src/lib/templates/flowchart-template.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FFTheme } from "../FFTheme";
import type { FFTheme } from "shared";

export const content = `
Brainstorming Session
Expand Down
2 changes: 1 addition & 1 deletion app/src/lib/templates/knowledge-graph-template.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FFTheme } from "../FFTheme";
import type { FFTheme } from "shared";

export const content = `
Fall of Ancient Rome .color_purple
Expand Down
2 changes: 1 addition & 1 deletion app/src/lib/templates/mindmap-template.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FFTheme } from "../FFTheme";
import type { FFTheme } from "shared";

export const content = `
Mind Mapping .size_lg
Expand Down
2 changes: 1 addition & 1 deletion app/src/lib/templates/org-chart-template.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FFTheme } from "../FFTheme";
import type { FFTheme } from "shared";

export const content = `
Saraswati Sharma .size_lg.color_pink
Expand Down
2 changes: 1 addition & 1 deletion app/src/lib/templates/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const templates: {
}[] = [
{
key: "default",
img: "template9.png",
img: "template21.png",
bgColor: "#FFFFFF",
title: () => `Default`,
promptType: "flowchart",
Expand Down
31 changes: 2 additions & 29 deletions app/src/lib/toTheme.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import cytoscape from "cytoscape";
import { Doc, useDoc } from "./useDoc";
import { Direction, FFTheme, LayoutDirection } from "./FFTheme";
import type { Doc } from "./useDoc";
import type { Direction, FFTheme, LayoutDirection } from "shared";
import { fonts } from "./fonts";
import {
childlessShapeClasses,
Expand Down Expand Up @@ -200,33 +200,6 @@ export function getThemeEditor(doc: Doc) {
return (doc.meta?.themeEditor as FFTheme) || defaultTheme;
}

export function useThemeEditor() {
return useDoc(
(state) => (state.meta?.themeEditor as FFTheme) || defaultTheme
);
}

export function useBackground() {
return useThemeEditor().background;
}

export function getBackground() {
return getThemeEditor(useDoc.getState()).background;
}

export function updateThemeEditor(theme: Partial<FFTheme>) {
useDoc.setState((doc) => ({
...doc,
meta: {
...doc.meta,
themeEditor: {
...getThemeEditor(doc),
...theme,
},
},
}));
}

function isHierarchical(layoutName: string) {
return ["dagre", "klay", "layered", "mrtree"].includes(layoutName);
}
Expand Down
31 changes: 31 additions & 0 deletions app/src/lib/toThemeDynamic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { FFTheme } from "shared";
import { theme as defaultTheme } from "./templates/default-template";
import { useDoc } from "./useDoc";
import { getThemeEditor } from "./toTheme";

export function useThemeEditor() {
return useDoc(
(state) => (state.meta?.themeEditor as FFTheme) || defaultTheme
);
}

export function useBackground() {
return useThemeEditor().background;
}

export function updateThemeEditor(theme: Partial<FFTheme>) {
useDoc.setState((doc) => ({
...doc,
meta: {
...doc.meta,
themeEditor: {
...getThemeEditor(doc),
...theme,
},
},
}));
}

export function getBackground() {
return getThemeEditor(useDoc.getState()).background;
}
2 changes: 1 addition & 1 deletion app/src/pages/New.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
createUnlimitedTitle,
} from "../lib/paywallCopy";
import { Warning } from "../components/Warning";
import { FFTheme } from "../lib/FFTheme";
import type { FFTheme } from "shared";

type CreateChartOptions = {
name: string;
Expand Down
Loading
Loading