Skip to content

Commit

Permalink
Merge pull request #15 from rohid-dev/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
iam-rohid authored Sep 10, 2022
2 parents cae9dfe + 25d7572 commit 41ee7cb
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 115 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "code-to-img",
"private": true,
"version": "1.2.0",
"version": "1.3.0",
"license": "MIT",
"author": {
"name": "Rohidul Islam",
Expand Down Expand Up @@ -66,6 +66,7 @@
},
"devDependencies": {
"@types/bcrypt": "^5.0.0",
"@types/gtag.js": "^0.0.11",
"@types/node": "^17.0.32",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
Expand Down
18 changes: 0 additions & 18 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
import { AppProps } from "next/app";
import { useRouter } from "next/router";
import { useEffect } from "react";
import Header from "../src/components/Header";
import SEO from "../src/components/SEO";
import { EditorProvider } from "../src/contexts/EditorContext";
import "../styles/global.css";
import * as gtag from "../src/lib/gtag";

const MyApp = ({ Component, pageProps }: AppProps) => {
const router = useRouter();

useEffect(() => {
const handleRouteChange = (url: string) => {
gtag.pageview(url);
};

router.events.on("routeChangeComplete", handleRouteChange);
router.events.on("hashChangeComplete", handleRouteChange);
return () => {
router.events.off("routeChangeComplete", handleRouteChange);
router.events.off("hashChangeComplete", handleRouteChange);
};
}, [router]);

return (
<EditorProvider>
<SEO />
Expand Down
23 changes: 12 additions & 11 deletions pages/_document.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import { Head, Html, Main, NextScript } from "next/document";
import Script from "next/script";
import * as gtag from "../src/lib/gtag";
import { GA_TRACKING_ID } from "../src/lib/gtag";

const MyDocument = () => {
return (
<Html>
<Head>
<Script
strategy="beforeInteractive"
src={`https://www.googletagmanager.com/gtag/js?id=${gtag.GA_TRACKING_ID}`}
/>
async
src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
></Script>
<Script
id="gtag-init"
id="google-analytics"
strategy="lazyOnload"
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${gtag.GA_TRACKING_ID}', {
page_path: window.location.pathname,
});
`,
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${GA_TRACKING_ID}', {
page_path: window.location.pathname,
});
`,
}}
/>
</Head>
Expand Down
20 changes: 0 additions & 20 deletions pages/api/hash-object.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Header = () => {
/>
<p>
<span className="font-bold text-xl text-white">CodeToImg</span>
<span className="text-xs ml-1">v1.2.0</span>
<span className="text-xs ml-1">v1.3.0</span>
</p>
</a>
</Link>
Expand Down
7 changes: 4 additions & 3 deletions src/components/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import { getExtentions } from "./Editor/get-extentions";
import { darkTheme, lightTheme } from "./Editor/themes";
import { useAtom } from "jotai";
import { appStateAtom } from "../stores/appState";
import { exportSettingsAtom } from "../stores/exportSettings";

const Preview = () => {
const [appState] = useAtom(appStateAtom);
const { canvasRef } = useEditor();

return (
<div
className={`w-full overflow-x-auto my-8 px-4 ${
className={`w-full overflow-x-auto my-8 px-4 mb-40 ${
appState.darkMode ? "dark" : ""
}`}
>
Expand Down Expand Up @@ -199,9 +200,9 @@ const TitleField = () => {
};

const WatterMark = () => {
const [appState] = useAtom(appStateAtom);
const [exportSettings] = useAtom(exportSettingsAtom);

if (!appState.showWaterMark) return null;
if (!exportSettings.showWaterMark) return null;
return (
<div className="absolute left-4 bottom-2 mix-blend-overlay opacity-50 text-white">
codetoimg.com
Expand Down
25 changes: 14 additions & 11 deletions src/components/ToolBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import * as Select from "@radix-ui/react-select";
import { useAtom } from "jotai";
import { appStateAtom } from "../stores/appState";
import { exportSettingsAtom } from "../stores/exportSettings";

const ToolBar = () => {
const [appState, setAppState] = useAtom(appStateAtom);
const [exportSettings, setExportSettings] = useAtom(exportSettingsAtom);

const { onExport, onCopyAsLink, onCopyAsImage, onReset } = useEditor();

return (
Expand Down Expand Up @@ -130,33 +133,33 @@ const ToolBar = () => {
<SelectItem
label="Format"
options={["png", "jpeg", "svg"]}
value={appState.renderFormat}
value={exportSettings.renderFormat}
onChange={(value) => {
setAppState({
...appState,
setExportSettings({
...exportSettings,
renderFormat: value,
});
}}
/>
<SelectItem
disabled={appState.renderFormat === "svg"}
disabled={exportSettings.renderFormat === "svg"}
label="Scale"
options={["1x", "2x", "3x"]}
value={appState.renderScale}
value={exportSettings.renderScale}
onChange={(value) => {
setAppState({
...appState,
setExportSettings({
...exportSettings,
renderScale: value,
});
}}
/>
<SwitchItem
label="Show Watermark"
value={appState.showWaterMark}
value={exportSettings.showWaterMark}
onChange={() =>
setAppState({
...appState,
showWaterMark: !appState.showWaterMark,
setExportSettings({
...exportSettings,
showWaterMark: !exportSettings.showWaterMark,
})
}
/>
Expand Down
120 changes: 84 additions & 36 deletions src/contexts/EditorContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import {
} from "react";
import { toPng, toJpeg, toSvg, toBlob } from "html-to-image";
import { Options } from "html-to-image/lib/types";
import axios from "axios";
import { useRouter } from "next/router";
import { useAtom } from "jotai";
import { AppState, appStateAtom, initAppState } from "../stores/appState";
import { exportSettingsAtom } from "../stores/exportSettings";
import * as gtag from "../lib/gtag";

export type EditorContextType = {
canvasRef: React.RefObject<HTMLDivElement>;
Expand All @@ -25,39 +26,72 @@ export type EditorContextType = {
export const EditorContext = createContext<EditorContextType | null>(null);

export const EditorProvider = ({ children }: { children: ReactNode }) => {
const [isLoading, setIsLoading] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [settings, setSettings] = useAtom(appStateAtom);
const [exportSettings] = useAtom(exportSettingsAtom);

const router = useRouter();

const getSettings = useCallback(async () => {
const { token } = router.query;
if (token) {
setIsLoading(true);
const { data } = await axios.get(`/api/hash-object?token=${token}`);
setSettings(data);
setIsLoading(false);
router.push("/");
}
}, [router, setSettings]);
let decodedQuery: any = Object.fromEntries(
new URLSearchParams(location.search)
);
Object.keys(decodedQuery).map((key) => {
switch (decodedQuery[key]) {
case "true":
decodedQuery[key] = true;
break;

case "false":
decodedQuery[key] = false;
break;

default:
break;
}
});

setSettings({
...initAppState,
...decodedQuery,
});

setIsLoading(false);
}, [setSettings]);

useEffect(() => {
getSettings();
}, [getSettings]);

useEffect(() => {
if (isLoading) return;
router.replace({
query: settings,
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [settings, isLoading]);

const canvasRef = useRef<HTMLDivElement>(null);

const getConvertOptions = (settings: AppState) => {
const scale =
settings.renderScale === "3x" ? 3 : settings.renderScale === "2x" ? 2 : 1;
console.log(scale);

const options: Options = {
canvasWidth: canvasRef.current.clientWidth * scale,
canvasHeight: canvasRef.current.clientHeight * scale,
quality: 0.95,
};
return options;
};
const getConvertOptions = useCallback(
(settings: AppState) => {
const scale =
exportSettings.renderScale === "3x"
? 3
: exportSettings.renderScale === "2x"
? 2
: 1;
console.log(scale);

const options: Options = {
canvasWidth: canvasRef.current.clientWidth * scale,
canvasHeight: canvasRef.current.clientHeight * scale,
quality: 0.95,
};
return options;
},
[exportSettings.renderScale]
);

const onExport: EditorContextType["onExport"] = useCallback(async () => {
if (!canvasRef.current) return;
Expand All @@ -66,12 +100,9 @@ export const EditorProvider = ({ children }: { children: ReactNode }) => {

var imgUrl: string | null = null;

const fileExtension = `.${settings.renderFormat.toLowerCase()}`;
const fileExtension = `.${exportSettings.renderFormat.toLowerCase()}`;

switch (fileExtension) {
case ".png":
imgUrl = await toPng(canvasRef.current, options);
break;
case ".jpeg":
imgUrl = await toJpeg(canvasRef.current, options);
break;
Expand All @@ -84,20 +115,28 @@ export const EditorProvider = ({ children }: { children: ReactNode }) => {
}

if (!imgUrl) return;

const filename = `${settings.filename || "Untitled"}${fileExtension}`;
const link = document.createElement("a");
link.download = `${settings.filename || "Untitled"}${fileExtension}`;
link.download = filename;
link.href = imgUrl;
link.click();
}, [settings, canvasRef]);

gtag.event({
action: "image_export",
category: "export",
label: location.href,
});
}, [getConvertOptions, settings, exportSettings.renderFormat]);

const onCopyAsLink: EditorContextType["onCopyAsLink"] =
useCallback(async () => {
const origin = window.location.origin;
const { data } = await axios.post(`/api/hash-object`, settings);
const link = `${origin}?token=${data.token}`;
window.navigator.clipboard.writeText(link);
}, [settings]);
window.navigator.clipboard.writeText(location.href);
gtag.event({
action: "copy_link",
category: "export",
label: location.href,
});
}, []);

const onCopyAsImage: EditorContextType["onCopyAsImage"] =
useCallback(async () => {
Expand All @@ -108,10 +147,19 @@ export const EditorProvider = ({ children }: { children: ReactNode }) => {
new ClipboardItem({ "image/png": blog }),
]);
console.log("Copied");
}, [settings]);
gtag.event({
action: "copy_image",
category: "export",
label: location.href,
});
}, [getConvertOptions, settings]);

const onReset = () => {
setSettings(initAppState);
gtag.event({
action: "reset",
category: "reset",
});
};
if (isLoading) return null;

Expand Down
Loading

1 comment on commit 41ee7cb

@vercel
Copy link

@vercel vercel bot commented on 41ee7cb Sep 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.