-
`}
-
- )${useTypeScript ? " as React.JSX.Element" : ""};
-}`
- },
-
- "hewwo:3": (useTypeScript, useTailwind) => {
- return `${useTailwind ? "import './hewwo.css'\n\n":""}export default function Hewwo() {
- const words${useTypeScript ? " : String[]":""} = ["owo", "OwO", "oWo", "Ōwò", "uwu", "UwU", "uWu", "iwi", "qwq", "pwp", "qwp", "TwT", "тwт", "TmT", "тmт", "ôWô", "òwó", "ùwú", ">w<", ">W<", "-w-", "-W-", "~w~", "~W~", ">m<", "omo", "OmO", "umu", "UmU", "-m-", "-M-", "~m~", "~M~", "owø", "^w^", ":3", ";3", "x3", "X3", ">:3", ">;3", ":3c", ";3c", ">:3c", ">;3c"];
- return (
-
hewwo warudo
{words[Math.round(Math.random() * words.length)]}
- )${useTypeScript ? " as React.JSX.Element" : ""};
-}`
- }
-}
\ No newline at end of file
diff --git a/files/common.js b/files/common.js
new file mode 100644
index 0000000..33a232c
--- /dev/null
+++ b/files/common.js
@@ -0,0 +1,92 @@
+export default {
+ ".gitignore": `# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+ # dependencies
+ /node_modules
+ /.pnp
+ .pnp.js
+
+ # testing
+ /coverage
+
+ # production
+ /build
+
+ # misc
+ .DS_Store
+ .env.local
+ .env.development.local
+ .env.test.local
+ .env.production.local
+
+ npm-debug.log*
+ yarn-debug.log*
+ yarn-error.log*`,
+
+ "README.md": (projectName) => `# ${projectName}\n###### Boilerplate generated using [npx create-deadcode-app](https://github.com/DeadCodeGames/create-deadcode-app)`,
+
+ "buildndeploy.yml": `name: Deploy to GitHub Pages
+on:
+ push:
+ branches:
+ - main
+ workflow_dispatch:
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+jobs:
+
+ # Build job
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Setup Node
+ uses: actions/setup-node@v4
+ with:
+ node-version: "14"
+
+ - name: Install dependencies
+ run: npm i
+
+ - name: Build project
+ run: CI=false && npm run build
+
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./build
+
+ # Deployment job
+ deploy:
+ environment:
+ name: github-pages
+ url: \${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4`,
+
+ "index.html": (projectName) => `
+
+
+
+
+
+
+
${projectName}
+
+
+
+
+
+`,
+}
\ No newline at end of file
diff --git a/files/config.js b/files/config.js
new file mode 100644
index 0000000..3a7e8b7
--- /dev/null
+++ b/files/config.js
@@ -0,0 +1,70 @@
+export default {
+ "tsconfig.json": `{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "allowImportingTsExtensions": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["src/*"]
+ }
+ },
+ "include": [
+ "src/**/*.ts",
+ "src/**/*.tsx"
+ ]
+ }`,
+
+ "config-overrides.js": `const path = require('path');
+
+ module.exports = function override(config) {
+ config.resolve.alias = {
+ ...config.resolve.alias,
+ '@': path.resolve(__dirname, 'src'),
+ };
+
+ return config;
+ };`,
+
+ "tailwind.config.js": (usingTS) => `/** @type {import('tailwindcss').Config} */
+ const defaultTheme = require("tailwindcss/defaultTheme");
+ module.exports = {
+ darkMode: ["class"],
+ content: ["src/**/*.{${usingTS ? "ts,tsx" : "js,jsx"}}"],
+ theme: {
+ extend: {
+ fontFamily: {
+ "consolas": ["Consolas", "Courier New", 'Courier', 'monospace'],
+ "uniSansCAPS": ["Uni Sans CAPS", ...defaultTheme.fontFamily.sans],
+ "montserrat": ["Montserrat", "Noto Sans JP", ...defaultTheme.fontFamily.sans],
+ },
+ keyframes: {
+ "heartPulse": {
+ '0%, 25%, 60%': { transform: 'scale(1)' },
+ '5%, 35%': { transform: 'scale(1.25)' },
+ }
+ },
+ animation: {
+ 'heart-pulse': 'heartPulse 0.9375s linear infinite',
+ },
+ },
+ },
+ }`,
+
+
+}
\ No newline at end of file
diff --git a/files/css.js b/files/css.js
new file mode 100644
index 0000000..f16a730
--- /dev/null
+++ b/files/css.js
@@ -0,0 +1,33 @@
+export default {
+ "input.css": `@tailwind base;
+ @tailwind components;
+ @tailwind utilities;
+ @import url('./fonts/fonts.css');
+ @import url("https://cdn.jsdelivr.net/gh/DeadCodeGames/DeadCodeGames.github.io@main/fonts/Uni%20Sans/stylesheet.css");
+
+ html, body {@apply m-0 bg-black text-white;} a {all: unset;@apply cursor-pointer underline m-[2.5px];} div.checklist pre.code { @apply border w-fit p-2 rounded-lg border-solid border-[#1F1F1F] bg-[#0F0F0F] my-4; }`,
+
+ "index.css": `html, body {
+ margin: 0px;
+ background: black;
+ color: white;
+ }
+
+ div#root>div#content {
+ display: grid;
+ grid-template-columns: 400px 350px auto;
+ grid-template-rows: 112.5px 440px auto;
+ padding: 33.3px 50px;
+ gap: 16.7px 25px;
+ }
+
+ div#content>div#title {
+ font-family: 'Consolas', 'Courier New', Courier, monospace;
+ font-size: 48px;
+ grid-row: 1;
+ grid-column: 1 / 3;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-evenly;
+ }`,
+}
\ No newline at end of file
diff --git a/files/electron.js b/files/electron.js
new file mode 100644
index 0000000..aa8fb9e
--- /dev/null
+++ b/files/electron.js
@@ -0,0 +1,578 @@
+export default {
+ "electron.main.js": `/**
+ * This is your main process file :3
+ * Here you can use node.js to control your application
+ * You can use ipcMain to listen to messages from the renderer process, and ipcRenderer to send messages to the renderer process
+ * For more info: https://www.electronjs.org/docs/latest/tutorial/process-model#the-main-process
+ */
+
+ const fs = require("fs")
+ const { app, BrowserWindow, ipcMain } = require('electron');
+ const path = require("path")
+ let installExtension, REACT_DEVELOPER_TOOLS;
+ if (!app.isPackaged) {
+ ({ default: installExtension, REACT_DEVELOPER_TOOLS } = require('electron-devtools-installer'));
+ }
+
+ let win;
+
+ function createWindow() {
+ win = new BrowserWindow({
+ minWidth: 450,
+ minHeight: 430,
+ width: 800,
+ height: 600,
+ frame: false,
+ webPreferences: {
+ devTools: !app.isPackaged,
+ preload: path.join(__dirname, "preload.js"),
+ contextIsolation: true,
+ nodeIntegration: false
+ }
+ });
+
+ win.loadURL(app.isPackaged ? \`file://\${path.join(__dirname, "../build/index.html")}\` : "http://localhost:3000");
+ if (!app.isPackaged) installExtension(REACT_DEVELOPER_TOOLS).then((name) => console.log(\`Added Extension: \${name}\`)).catch((err) => console.log('An error occurred: ', err));
+
+ win.on('maximize', () => {
+ win.webContents.send('window-maximized');
+ });
+
+ win.on('unmaximize', () => {
+ win.webContents.send('window-unmaximized');
+ });
+ }
+
+ app.on('ready', createWindow);
+
+ ipcMain.on('window-control', (event, action) => {
+ // eslint-disable-next-line default-case
+ switch (action) {
+ case 'minimize':
+ win.minimize();
+ break;
+ case 'maximize':
+ if (win.isMaximized()) {
+ win.unmaximize();
+ } else {
+ win.maximize();
+ }
+ break;
+ case 'close':
+ win.close();
+ break;
+ }
+ });
+
+ ipcMain.handle('is-window-maximized', () => {
+ return win.isMaximized();
+ });
+
+ ipcMain.handle('get-process-platform', () => {
+ switch (process.platform) {
+ case 'win32':
+ return 'Windows';
+ case 'linux':
+ return 'Linux';
+ case 'darwin':
+ return 'Mac';
+ default:
+ return 'Linux';
+ }
+ })
+
+ ipcMain.on('update-preferences', (event, preferences) => {
+ fs.writeFileSync(path.join(app.getPath("userData"), "./preferences.json"), JSON.stringify(preferences));
+ })
+
+ ipcMain.handle('get-preferences', async () => {
+ let prefs;
+ try {
+ prefs = fs.readFileSync(path.join(app.getPath("userData"), "./preferences.json"), "utf-8");
+ } catch (err) {
+ if (err.code === 'ENOENT') {
+ console.log('preferences.json not found - creating new one with default values');
+ fs.writeFileSync(path.join(app.getPath("userData"), "./preferences.json"), JSON.stringify({ theme: 'dark' }));
+ return { theme: 'dark' };
+ } else {
+ console.error(err);
+ }
+ }
+ return JSON.parse(prefs);
+ })`,
+
+ "electron.preload.js": `/* this is your preload environment file :3
+ * you can use this to expose node APIs to renderer
+ * please, use this CAREFULLY! Only and ONLY expose what you need, and NOTHING MORE!
+ * for more info: https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts
+ */
+
+ const { contextBridge, ipcRenderer } = require("electron")
+
+ contextBridge.exposeInMainWorld('Electron', {
+ minimize: () => ipcRenderer.send('window-control', 'minimize'),
+ maximize: () => ipcRenderer.send('window-control', 'maximize'),
+ close: () => ipcRenderer.send('window-control', 'close'),
+ isMaximized: () => ipcRenderer.invoke('is-window-maximized'),
+ getPlatform: () => ipcRenderer.invoke('get-process-platform'),
+ onMaximize: (callback) => ipcRenderer.on('window-maximized', callback),
+ onUnmaximize: (callback) => ipcRenderer.on('window-unmaximized', callback),
+ getPreferences: () => ipcRenderer.invoke('get-preferences'),
+ updatePreferences: (preferences) => ipcRenderer.send('update-preferences', preferences)
+ });`,
+
+ "electron.WinControls.css": `div#window {
+ top: 0;
+ left: 0;
+ position: absolute;
+ height: 40px;
+ width: -webkit-fill-available;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ -webkit-app-region: drag;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ }
+ @import url(./windows.WinControls.css);
+ @import url(./mac.WinControls.css);
+ @import url(./linux.WinControls.css)`,
+
+ "electron.windows.WinControls.css": `div#window[data-type="windows"] {
+ padding: 0 0 0 10px;
+ }
+
+ div#window[data-type="windows"]>div#titleright>div#controls, div#window[data-type="windows"]>div#titleright>div#controls>* {
+ -webkit-app-region: no-drag;
+ font-size: 16px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ cursor: pointer;
+ height: 100%;
+ text-align: center;
+ justify-content: center;
+ }
+
+ div#window[data-type="windows"]>div#titleleft, div#window[data-type="windows"]>div#titleright {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ height: 100%;
+ }
+
+ div#window[data-type="windows"]>div#titleleft>div#windowtitle {
+ font-family: 'Cascadia Mono', 'Consolas', monospace, 'Uni Sans CAPS', 'Montserrat', sans-serif;
+ font-size: 14px;
+ font-weight: 700;
+ user-select: none;
+ -webkit-user-select: none;
+ padding-left: 4px;
+ font-style: italic;
+ }
+
+ div#window[data-type="windows"]>div#titleright>div#controls>* {
+ height: 100%;
+ aspect-ratio: 1;
+ }
+
+ div#window[data-type="windows"]>div#titleright>div#controls>div#close, div#window[data-type="windows"]>div#titleright>div#controls>div#themechange {
+ font-size: 20px !important;
+ }
+
+ div#window[data-type="windows"]>div#titleright>div#controls>div#close:hover {
+ background-color: red
+ }
+
+ div#window[data-type="windows"]>div#titleright>div#controls>* {
+ transition: background 0.125s ease-in-out
+ }
+
+ html.light {
+ div#window[data-type="windows"] {
+ background: #E9E9E9;
+ }
+
+ div#window[data-type="windows"]>div#titleright>div#controls, div#window[data-type="windows"]>div#titleright>div#controls>* {
+ color: black;
+ }
+
+ div#window[data-type="windows"]>div#titleright>div#controls>div#minimize:hover, div#window[data-type="windows"]>div#titleright>div#controls>div#maximize:hover, div#window[data-type="windows"]>div#titleright>div#controls>div#themechange:hover {
+ background-color: rgba(0, 0, 0, 0.25)
+ }
+
+ div#window[data-type="windows"]>div#titleleft>* {
+ color: #0F0F0F;
+ }
+ }
+
+ html.dark {
+ div#window[data-type="windows"] {
+ background: #161616;
+ }
+
+ div#window[data-type="windows"]>div#titleright>div#controls, div#window[data-type="windows"]>div#titleright>div#controls>* {
+ color: white;
+ }
+
+ div#window[data-type="windows"]>div#titleright>div#controls>div#minimize:hover, div#window[data-type="windows"]>div#titleright>div#controls>div#maximize:hover, div#window[data-type="windows"]>div#titleright>div#controls>div#themechange:hover {
+ background-color: rgba(255, 255, 255, 0.25)
+ }
+
+ div#window[data-type="windows"]>div#titleleft>* {
+ color: #F0F0F0;
+ }
+ }`,
+
+ "electron.linux.WinControls.css": `div#window[data-type="linux"] {
+ padding-left: 0;
+ }
+
+ div#window[data-type="linux"]::before {
+ content: "";
+ width: 135px;
+ }
+
+ div#window[data-type="linux"]>div#titlemiddle>div#windowtitle {
+ font-family: 'Cascadia Mono', 'Consolas', monospace, 'Uni Sans CAPS', 'Montserrat', sans-serif;
+ font-size: 14px;
+ font-weight: 700;
+ user-select: none;
+ -webkit-user-select: none;
+ padding-left: 4px;
+ font-style: italic;
+ }
+
+ div#window[data-type="linux"]>div#titleright>div#controls, div#window[data-type="linux"]>div#titleright>div#controls>* {
+ -webkit-app-region: no-drag;
+ font-size: 14px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ height: 100%;
+ text-align: center;
+ justify-content: center;
+ }
+
+ div#window[data-type="linux"]>div#titleright>div#controls>* {
+ cursor: pointer;
+ }
+
+ div#window[data-type="linux"]>div#titleright>div#controls {
+ padding: 11px 12px;
+ column-gap: 13px;
+ }
+
+ div#window[data-type="linux"]>div#titleright>div#controls>* {
+ padding: 2px;
+ border-radius: 100%;
+ }
+
+ html.dark {
+ div#window[data-type="linux"] {
+ background: #161616;
+ color: #F0F0F0;
+ }
+
+ div#window[data-type="linux"]>div#titleright>div#controls>* {
+ background: #2C2C2C;
+ }
+
+ div#window[data-type="linux"]>div#titleright>div#controls>*:hover {
+ background: #3E3E3E;
+ }
+ }
+
+ html.light {
+ div#window[data-type="linux"] {
+ background: #E9E9E9;
+ color: #0F0F0F;
+ }
+
+ div#window[data-type="linux"]>div#titleright>div#controls>* {
+ background: #D3D3D3;
+ }
+
+ div#window[data-type="linux"]>div#titleright>div#controls>* {
+ background: #C1C1C1;
+ }
+ }`,
+
+ "electron.mac.WinControls.css": `div#window[data-type="mac"]::after {
+ content: "";
+ width: 118px;
+ }
+
+ div#window[data-type="mac"]>div#titlemiddle>div#windowtitle {
+ font-family: 'Cascadia Mono', 'Consolas', monospace, 'Uni Sans CAPS', 'Montserrat', sans-serif;
+ font-size: 14px;
+ font-weight: 700;
+ user-select: none;
+ -webkit-user-select: none;
+ padding-left: 4px;
+ font-style: italic;
+ }
+
+ div#window[data-type="mac"]>div#titleleft>div#controls, div#window[data-type="mac"]>div#titleleft>div#controls>* {
+ -webkit-app-region: no-drag;
+ font-size: 14px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ height: 100%;
+ text-align: center;
+ justify-content: center;
+ }
+
+ div#window[data-type="mac"]>div#titleleft>div#controls>* {
+ cursor: pointer;
+ color: transparent;
+ transition: color 0.25s ease;
+ }
+
+ div#window[data-type="mac"]>div#titleleft>div#controls {
+ padding: 11px 12px;
+ column-gap: 10px;
+ & div#close {
+ background: red !important;
+ }
+ & div#minimize {
+ background: #FFD200 !important
+ }
+ & div#maximize {
+ background: limegreen !important
+ }
+ }
+
+ div#window[data-type="mac"]>div#titleleft>div#controls>*:hover {
+ color: rgba(0, 0, 0, 0.75);
+ }
+
+ div#window[data-type="mac"]>div#titleleft>div#controls>* {
+ padding: 0px;
+ border-radius: 100%;
+ }
+
+ html.dark {
+ div#window[data-type="mac"] {
+ background: #161616;
+ color: #F0F0F0;
+ }
+ div#window[data-type="mac"]>div#titleleft>div#controls>div#themechange {
+ background: #F0F0F0;
+ }
+ div#window[data-type="mac"]>div#titleleft>div#controls>div#themechange:hover {
+ color: black !important;
+ }
+ }
+
+ html.light {
+ div#window[data-type="mac"] {
+ background: #E9E9E9;
+ color: #0F0F0F;
+ }
+ div#window[data-type="mac"]>div#titleleft>div#controls>div#themechange {
+ background: #0F0F0F;
+ }
+ div#window[data-type="mac"]>div#titleleft>div#controls>div#themechange:hover {
+ color: white !important;
+ }
+ }`,
+
+ "electron.WinControls": (projectName, useTypeScript, useTailwind) => {
+ const tailwindStyles = {
+ "#window": "absolute h-10 w-[-webkit-fill-available] flex justify-between items-center flex-row flex-nowrap left-0 top-0 app-region-drag bg-[#e9e9e9] dark:bg-[#161616]",
+
+ "#window[data-type='windows']": "pl-2.5 pr-0 py-0",
+ "#window[data-type='windows']>div#titleright>div#controls": "flex flex-row items-center cursor-pointer h-full text-center justify-center app-region-no-drag",
+ "#window[data-type='windows']>div#titleleftandright": "flex flex-row items-center h-full",
+ "#window[data-type='windows'] div#windowtitle": "text-sm font-bold select-none italic pl-1 font-consolas text-[#0F0F0F] dark:text-[#F0F0F0]",
+ "#window[data-type='windows'] div#controls": "*:h-full *:aspect-[1] *:transition-[background] *:duration-[0.125s] *:ease-[ease-in-out] *:flex *:items-center *:justify-center text-black dark:text-white",
+ "#window[data-type='windows'] div#themechangeandclose": "text-xl",
+ "#window[data-type='windows'] div#notthemechangeorclose": "text-base",
+ "#window[data-type='windows'] div#closehover": "hover:bg-[red]",
+ "#window[data-type='windows'] div#notclosehover": "hover:bg-[rgba(0,0,0,0.25)] dark:hover:bg-[rgba(255,255,255,0.25)]",
+
+ "#window[data-type='mac']": "bg-[#E9E9E9] text-[#0F0F0F] dark:bg-[#161616] dark:text-[#F0F0F0] after:content-[''] after:w-[118px]",
+ "#window[data-type='mac'] div#windowtitle": "text-sm font-bold select-none italic pl-1 font-consolas",
+ "#window[data-type='mac'] div#controls": "text-sm flex flex-row items-center h-full text-center justify-center app-region-no-drag gap-x-2.5 px-3 py-[11px]",
+ "#window[data-type='mac'] div#controls>*": "*:text-sm *:flex *:flex-row *:items-center *:h-full *:text-center *:justify-center *:app-region-no-drag *:cursor-pointer *:text-transparent *:transition-[color] *:duration-[0.25s] *:ease-[ease] *:p-0 *:rounded-[100%] hover:text-[rgba(0,0,0,0.75)]",
+ "#window[data-type='mac'] div#close": "bg-[red]",
+ "#window[data-type='mac'] div#minimize": "bg-[#FFD200]",
+ "#window[data-type='mac'] div#maximize": "bg-[limegreen]",
+ "#window[data-type='mac'] div#themechange": "bg-[#0F0F0F] hover:text-[white] dark:bg-[#F0F0F0] dark:hover:text-[black]",
+ }
+ return `import { useEffect, useState, useContext } from 'react';${!useTailwind ? '\nimport "./WinControls.css";' : ''}
+ import { AppContext } from '${"../.."}/App.${useTypeScript ? "tsx" : "jsx"}';
+
+ export default function WinControls({type}${useTypeScript ? ': {type: null | "Linux" | "Windows" | "Mac"}' : ''}) {
+ const {context, setContext} = useContext(AppContext);
+ const [isMaximized, setIsMaximized] = useState${useTypeScript ? "
" : ""}(false);
+
+ useEffect(() => {
+ const checkIfMaximized = async () => {
+ const result${useTypeScript ? " : Boolean" : ""} = await window.Electron.isMaximized();
+ setIsMaximized(result);
+ };
+
+ checkIfMaximized();
+
+ window.Electron.onMaximize(() => {
+ setIsMaximized(true);
+ });
+
+ window.Electron.onUnmaximize(() => {
+ setIsMaximized(false);
+ });
+
+ return () => {
+ window.Electron.onMaximize(() => {});
+ window.Electron.onUnmaximize(() => {});
+ };
+ }, []);
+
+ const handleMinimize = () => {
+ window.Electron.minimize();
+ };
+
+ const handleMaximize = () => {
+ window.Electron.maximize();
+ setIsMaximized(!isMaximized);
+ };
+
+ const handleClose = () => {
+ window.Electron.close();
+ };
+
+ const handleThemeChange = () => {
+ if (document.documentElement.classList.contains("dark")) {
+ document.documentElement.classList.remove("dark"); document.documentElement.classList.add("light");
+ setContext({ ...context, preferences: { ...context.preferences, theme: "light" } })
+ } else {
+ document.documentElement.classList.remove("light"); document.documentElement.classList.add("dark")
+ setContext({ ...context, preferences: { ...context.preferences, theme: "dark" } })
+ }
+ }
+
+ const [htmlClass, setHtmlClass] = useState${useTypeScript ? "" : ""}(document.documentElement.className);
+
+ document.documentElement.classList.add(context.preferences.theme === "dark" ? "dark" : "light");
+ document.documentElement.classList.remove(context.preferences.theme === "dark" ? "light" : "dark");
+
+ useEffect(() => {
+ const observer = new MutationObserver(() => {
+ setHtmlClass(document.documentElement.className);
+ });
+
+ observer.observe(document.documentElement, {
+ attributes: true,
+ attributeFilter: ['class']
+ });
+
+ return () => {
+ observer.disconnect();
+ };
+ }, []);
+
+ switch (type) {
+ default:
+ return (
+
+
div#titleleftandright"]}"` : ""}>
+
${projectName}
+
+
div#titleleftandright"]}"` : ""}>
+
div#titleright>div#controls"]} ${tailwindStyles["#window[data-type='windows'] div#controls"]}"` : ""}>
+
{ htmlClass.includes("dark") ? ("light_mode") : ("dark_mode")}
+
horizontal_rule
+
{ isMaximized ? ("stack") : ("square")}
+
close
+
+
+
+ )${useTypeScript ? " as React.JSX.Element" : ""};
+ case "Windows":
+ return (
+
+
div#titleleftandright"]}"` : ""}>
+
${projectName}
+
+
div#titleleftandright"]}"` : ""}>
+
div#titleright>div#controls"]} ${tailwindStyles["#window[data-type='windows'] div#controls"]}"` : ""}>
+
{ htmlClass.includes("dark") ? ("light_mode") : ("dark_mode")}
+
horizontal_rule
+
{ isMaximized ? ("stack") : ("square")}
+
close
+
+
+
+ )${useTypeScript ? " as React.JSX.Element" : ""};
+ case "Mac":
+ return (
+
+
+
+
close
+
horizontal_rule
+
{ isMaximized ? ("collapse_content") : ("expand_content")}
+
{ htmlClass.includes("dark") ? ("light_mode") : ("dark_mode")}
+
+
+
+
+ )${useTypeScript ? " as React.JSX.Element" : ""};
+ case "Linux":
+ return (
+
+
+
+
*"]}"` : ""}>
+
{ htmlClass.includes("dark") ? ("light_mode") : ("dark_mode")}
+
horizontal_rule
+
{ isMaximized ? ("collapse_content") : ("expand_content")}
+
close
+
+
+
+ )${useTypeScript ? " as React.JSX.Element" : ""};
+ }
+ }`
+ },
+
+ "electron.extraTypes": `import {IpcRendererEvent} from 'electron'
+ declare global {
+ interface Window {
+ Electron: {
+ minimize: () => void;
+ maximize: () => void;
+ close: () => void;
+ isMaximized: () => Promise;
+ getPlatform: () => Promise<"Linux" | "Windows" | "Mac">;
+ onMaximize: (callback: (event: IpcRendererEvent) => void) => void;
+ onUnmaximize: (callback: (event: IpcRendererEvent) => void) => void;
+ getPreferences: () => object;
+ updatePreferences: (preferences: object) => void
+ };
+ }
+ }`,
+
+ "electron.preloadTypes": `declare namespace Electron {
+ interface MainWorld {
+ Electron: {
+ minimize: () => void;
+ maximize: () => void;
+ close: () => void;
+ isMaximized: () => boolean;
+ getPlatform: () => string;
+ onMaximize: (callback: (event: Electron.IpcRendererEvent) => void) => void;
+ onUnmaximize: (callback: (event: Electron.IpcRendererEvent) => void) => void;
+ getPreferences: () => object;
+ updatePreferences: (preferences: object) => void;
+ };
+ }
+ }`,
+}
\ No newline at end of file
diff --git a/fonts.zip b/files/fonts.zip
similarity index 100%
rename from fonts.zip
rename to files/fonts.zip
diff --git a/files/react.js b/files/react.js
new file mode 100644
index 0000000..5228d69
--- /dev/null
+++ b/files/react.js
@@ -0,0 +1,83 @@
+export default {
+ "indexReact": (usingTS, usingTailwind) => `import React from 'react';
+ import ReactDOM from 'react-dom/client';
+ ${usingTailwind ? "import './input.css';" : "import './index.css';"}
+ import App from './App';${!usingTailwind ? "\nimport './fonts/fonts.css'" : ""}
+
+ const root${usingTS ? " : ReactDOM.Root" : ""} = ReactDOM.createRoot(document.getElementById('root')${usingTS ? " as HTMLElement" : ""});
+ root.render(
+
+
+
+ );`,
+
+ "AppReact": (usingRouter, usingElectron, useTypeScript) => {
+ return `import { useState, useEffect, createContext } from "react"${usingRouter ? `import { ${usingElectron ? "HashRouter" : "BrowserRouter"} as Router, Routes, Route } from 'react-router-dom'\n` : ""}${usingElectron ? `import WinControls from './components/WinControls/WinControls.${useTypeScript ? "tsx" : "jsx"}'\n` : ""}
+
+export const AppContext = createContext${useTypeScript ? "" : ""}({ preferences: { theme: 'dark' } });
+
+function AppContextProvider({ children }${": { children: React.ReactNode }"}) {
+ const [context, setContext] = useState${useTypeScript ? "" : ""}({ preferences: { theme: 'dark' } });
+ const [shouldSetContext, setShouldSetContext] = useState${useTypeScript ? "" : ""}(false);
+
+ useEffect(() => {
+ const fetchPreferences = async () => {
+ try {
+ const prefs = await window.Electron.getPreferences();
+ setContext({ preferences: prefs });
+ console.log(prefs)
+ setShouldSetContext(true);
+ } catch (error) {
+ console.error('Failed to fetch client preferences:', error);
+ }
+ };
+
+ fetchPreferences();
+ }, []);
+
+ useEffect(() => {
+ if (shouldSetContext) window.Electron.updatePreferences(context.preferences)
+ }, [context, shouldSetContext]);
+
+ return (
+
+ {children}
+
+ )${useTypeScript ? " as React.JSX.Element" : ""};
+}
+
+export default function App() {${usingElectron ? `\n const [platform, setPlatform] = useState${useTypeScript ? '<"Linux" | "Windows" | "Mac" | null>' : ""}(null);
+ useEffect(() => {
+ async function getPlatform() {
+ const platform = await window.Electron.getPlatform();
+ setPlatform(platform);
+ }
+ getPlatform();
+ }, []);` : ""}
+
+ return (
+ ${usingRouter ? `\n ${usingElectron ? `
+ ` : ""}
+
+
+
+
+
+ ` : `${usingElectron ? `
+ ` : ""}
+
+
`}
+
+ )${useTypeScript ? " as React.JSX.Element" : ""};
+}`
+ },
+
+ "hewwo:3": (useTypeScript, useTailwind) => {
+ return `${useTailwind ? "import './hewwo.css'\n\n":""}export default function Hewwo() {
+ const words${useTypeScript ? " : String[]":""} = ["owo", "OwO", "oWo", "Ōwò", "uwu", "UwU", "uWu", "iwi", "qwq", "pwp", "qwp", "TwT", "тwт", "TmT", "тmт", "ôWô", "òwó", "ùwú", ">w<", ">W<", "-w-", "-W-", "~w~", "~W~", ">m<", "omo", "OmO", "umu", "UmU", "-m-", "-M-", "~m~", "~M~", "owø", "^w^", ":3", ";3", "x3", "X3", ">:3", ">;3", ":3c", ";3c", ">:3c", ">;3c"];
+ return (
+
hewwo warudo
{words[Math.round(Math.random() * words.length)]}
+ )${useTypeScript ? " as React.JSX.Element" : ""};
+}`
+ }
+}
\ No newline at end of file
diff --git a/index.js b/index.js
index 8142983..25a5ae4 100644
--- a/index.js
+++ b/index.js
@@ -349,46 +349,46 @@ async function main({ name, lang, framework, css, type, router, norouter, ghpage
const packageJSONPath = path.join(projectPath, "package.json");
tryCreateFileWithData(packageJSONPath, JSON.stringify(packageJSON, null, 2));
- tryCreateFileWithData(path.join(projectPath, "README.md"), files["README.md"](projectName));
- if (!keepGitignore) tryCreateFileWithData(path.join(projectPath, ".gitignore"), files[".gitignore"]);
+ tryCreateFileWithData(path.join(projectPath, "README.md"), files.common["README.md"](projectName));
+ if (!keepGitignore) tryCreateFileWithData(path.join(projectPath, ".gitignore"), files.common[".gitignore"]);
if (useGitHubPages) {
tryCreateDirectory(path.join(projectPath, ".github", "workflows"));
- tryCreateFileWithData(path.join(projectPath, ".github", "workflows", "buildndeploy.yml"), files["buildndeploy.yml"]);
+ tryCreateFileWithData(path.join(projectPath, ".github", "workflows", "buildndeploy.yml"), files.common["buildndeploy.yml"]);
}
tryCreateDirectory(path.join(projectPath, "public"), path.join(projectPath, "src"));
- tryCreateFileWithData(path.join(projectPath, "public", "index.html"), files["index.html"](projectName));
- tryCreateFileWithData(path.join(projectPath, "src", language.includes("TypeScript") ? "index.tsx" : "index.js"), files["indexReact"](language.includes("TypeScript"), cssFramework.includes("Tailwind")));
- if (language.includes("TypeScript")) tryCreateFileWithData(path.join(projectPath, "tsconfig.json"), files["tsconfig.json"]);
- if (useReactAppRewired) tryCreateFileWithData(path.join(projectPath, "config-overrides.js"), files["config-overrides.js"]);
+ tryCreateFileWithData(path.join(projectPath, "public", "index.html"), files.common["index.html"](projectName));
+ tryCreateFileWithData(path.join(projectPath, "src", language.includes("TypeScript") ? "index.tsx" : "index.js"), files.react["indexReact"](language.includes("TypeScript"), cssFramework.includes("Tailwind")));
+ if (language.includes("TypeScript")) tryCreateFileWithData(path.join(projectPath, "tsconfig.json"), files.config["tsconfig.json"]);
+ if (useReactAppRewired) tryCreateFileWithData(path.join(projectPath, "config-overrides.js"), files.config["config-overrides.js"]);
if (cssFramework.includes("Tailwind")) {
- tryCreateFileWithData(path.join(projectPath, "tailwind.config.js"), files["tailwind.config.js"](language.includes("TypeScript")));
- tryCreateFileWithData(path.join(projectPath, "src", "input.css"), files["input.css"]);
+ tryCreateFileWithData(path.join(projectPath, "tailwind.config.js"), files.config["tailwind.config.js"](language.includes("TypeScript")));
+ tryCreateFileWithData(path.join(projectPath, "src", "input.css"), files.css["input.css"]);
} else {
- tryCreateFileWithData(path.join(projectPath, "src", "index.css"), files["index.css"]);
+ tryCreateFileWithData(path.join(projectPath, "src", "index.css"), files.css["index.css"]);
}
if (appType.includes("Electron")) {
- tryCreateFileWithData(path.join(projectPath, "public", "main.js"), files["electron.main.js"]);
- tryCreateFileWithData(path.join(projectPath, "public", "preload.js"), files["electron.preload.js"]);
+ tryCreateFileWithData(path.join(projectPath, "public", "main.js"), files.electron["electron.main.js"]);
+ tryCreateFileWithData(path.join(projectPath, "public", "preload.js"), files.electron["electron.preload.js"]);
tryCreateDirectory(path.join(projectPath, "src", "components", "WinControls"));
if (cssFramework.includes("Vanilla CSS")) {
- tryCreateFileWithData(path.join(projectPath, "src", "components", "WinControls", "WinControls.css"), files["electron.WinControls.css"]);
- tryCreateFileWithData(path.join(projectPath, "src", "components", "WinControls", "windows.WinControls.css"), files["electron.windows.WinControls.css"]);
- tryCreateFileWithData(path.join(projectPath, "src", "components", "WinControls", "mac.WinControls.css"), files["electron.mac.WinControls.css"]);
- tryCreateFileWithData(path.join(projectPath, "src", "components", "WinControls", "linux.WinControls.css"), files["electron.linux.WinControls.css"]);
- tryCreateFileWithData(path.join(projectPath, "src", "components", "WinControls", `WinControls.${language.includes("TypeScript") ? "tsx" : "jsx"}`), files["electron.WinControls"](projectName, language.includes("TypeScript"), false));
+ tryCreateFileWithData(path.join(projectPath, "src", "components", "WinControls", "WinControls.css"), files.electron["electron.WinControls.css"]);
+ tryCreateFileWithData(path.join(projectPath, "src", "components", "WinControls", "windows.WinControls.css"), files.electron["electron.windows.WinControls.css"]);
+ tryCreateFileWithData(path.join(projectPath, "src", "components", "WinControls", "mac.WinControls.css"), files.electron["electron.mac.WinControls.css"]);
+ tryCreateFileWithData(path.join(projectPath, "src", "components", "WinControls", "linux.WinControls.css"), files.electron["electron.linux.WinControls.css"]);
+ tryCreateFileWithData(path.join(projectPath, "src", "components", "WinControls", `WinControls.${language.includes("TypeScript") ? "tsx" : "jsx"}`), files.electron["electron.WinControls"](projectName, language.includes("TypeScript"), false));
} else {
- tryCreateFileWithData(path.join(projectPath, "src", "components", "WinControls", `WinControls.${language.includes("TypeScript") ? "tsx" : "jsx"}`), files["electron.WinControls"](projectName, language.includes("TypeScript"), true));
+ tryCreateFileWithData(path.join(projectPath, "src", "components", "WinControls", `WinControls.${language.includes("TypeScript") ? "tsx" : "jsx"}`), files.electron["electron.WinControls"](projectName, language.includes("TypeScript"), true));
}
if (language.includes("TypeScript")) {
- tryCreateFileWithData(path.join(projectPath, "src", "electron.d.ts"), files["electron.extraTypes"])
+ tryCreateFileWithData(path.join(projectPath, "src", "electron.d.ts"), files.electron["electron.extraTypes"])
}
}
- tryCreateFileWithData(path.join(projectPath, "src", `App.${language.includes("TypeScript") ? "tsx" : "jsx"}`), files["AppReact"](useRouter, appType.includes("Electron"), language.includes("TypeScript")));
+ tryCreateFileWithData(path.join(projectPath, "src", `App.${language.includes("TypeScript") ? "tsx" : "jsx"}`), files.react["AppReact"](useRouter, appType.includes("Electron"), language.includes("TypeScript")));
tryCreateDirectory(path.join(projectPath, "src", "components", "Hewwo"));
- tryCreateFileWithData(path.join(projectPath, "src", "components", "Hewwo", `Hewwo.${language.includes("TypeScript") ? "tsx" : "jsx"}`), files["hewwo:3"](language.includes("TypeScript"), cssFramework.includes("Tailwind")));
+ tryCreateFileWithData(path.join(projectPath, "src", "components", "Hewwo", `Hewwo.${language.includes("TypeScript") ? "tsx" : "jsx"}`), files.react["hewwo:3"](language.includes("TypeScript"), cssFramework.includes("Tailwind")));
console.log(process.argv[1], path.dirname(process.argv[1]));
const runIsDir = await statSync(process.argv[1]);
- tryUnzip(path.join(runIsDir.isDirectory() ? process.argv[1] : path.dirname(process.argv[1]), "fonts.zip"), path.join(projectPath, "src"));
+ tryUnzip(path.join(runIsDir.isDirectory() ? process.argv[1] : path.dirname(process.argv[1]), "files", "fonts.zip"), path.join(projectPath, "src"));
}
const argv = Object.fromEntries(