mirror of
https://github.com/upscayl/upscayl.git
synced 2024-11-27 17:00:52 +01:00
Working code
This commit is contained in:
parent
f4b7c12688
commit
5941ed6a84
@ -14,8 +14,8 @@ app.on("ready", async () => {
|
||||
await prepareNext("./renderer");
|
||||
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 400,
|
||||
height: 750,
|
||||
width: 1100,
|
||||
height: 700,
|
||||
webPreferences: {
|
||||
autoHideMenuBar: true,
|
||||
nodeIntegration: false,
|
||||
@ -31,7 +31,7 @@ app.on("ready", async () => {
|
||||
});
|
||||
|
||||
mainWindow.setMenuBarVisibility(false);
|
||||
mainWindow.setResizable(false);
|
||||
mainWindow.maximize();
|
||||
mainWindow.loadURL(url);
|
||||
});
|
||||
|
||||
@ -39,43 +39,6 @@ app.on("ready", async () => {
|
||||
app.on("window-all-closed", app.quit);
|
||||
|
||||
// listen the channel `message` and resend the received message to the renderer process
|
||||
ipcMain.on("message", (event, message) => {
|
||||
ipcMain.on("sendMessage", (_, message) => {
|
||||
console.log(message);
|
||||
let text = `[Desktop Entry]
|
||||
Encoding=UTF-8
|
||||
Name=${message.name}
|
||||
Comment=${message.comment}
|
||||
Exec=${message.exec}
|
||||
Icon=${message.icon}
|
||||
Terminal=${message.terminal}
|
||||
Type=Application
|
||||
Categories=GNOME;Application;Utility;
|
||||
`;
|
||||
|
||||
try {
|
||||
const homePath = app.getPath("home");
|
||||
let filePath =
|
||||
homePath +
|
||||
"/.local/share/applications/" +
|
||||
message.name.replace(/[^A-Z0-9]+/gi, "_") +
|
||||
".desktop";
|
||||
|
||||
console.log(filePath);
|
||||
|
||||
fs.writeFileSync(filePath, text, "utf-8");
|
||||
|
||||
exec(`chmod +x ${filePath}`, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.log(`error: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
if (stderr) {
|
||||
console.log(`stderr: ${stderr}`);
|
||||
return;
|
||||
}
|
||||
console.log(`stdout: ${stdout}`);
|
||||
});
|
||||
} catch (e) {
|
||||
alert("Failed to save the file !");
|
||||
}
|
||||
});
|
||||
|
@ -1,5 +1,4 @@
|
||||
const { ipcRenderer, contextBridge } = require("electron");
|
||||
|
||||
contextBridge.exposeInMainWorld("electron", {
|
||||
message: (data) => ipcRenderer.send("message", data),
|
||||
});
|
||||
// 'ipcRenderer' will be available in index.js with the method 'window.electron'
|
||||
contextBridge.exposeInMainWorld("electron", ipcRenderer);
|
||||
|
27
package.json
27
package.json
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "deskcut",
|
||||
"name": "upscayl",
|
||||
"private": true,
|
||||
"version": "1.5.1",
|
||||
"productName": "DeskCut",
|
||||
"productName": "Upscayl",
|
||||
"author": "Nayam Amarshe <nayam@nay.am>",
|
||||
"email": "nay@am.com",
|
||||
"license": "GPLv2",
|
||||
"description": "DeskCut is an extremely easy to use desktop shortcut creator app for Linux",
|
||||
"description": "Upscayl - Linux first image upscale app",
|
||||
"keywords": [
|
||||
"Linux",
|
||||
"Gnome",
|
||||
@ -43,20 +43,19 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.2",
|
||||
"electron": "^12.0.2",
|
||||
"electron-builder": "^22.14.5",
|
||||
"next": "latest",
|
||||
"postcss": "^8.4.6",
|
||||
"prettier": "^2.5.1",
|
||||
"prettier-plugin-tailwindcss": "^0.1.5",
|
||||
"autoprefixer": "^10.4.8",
|
||||
"electron": "^20.0.2",
|
||||
"electron-builder": "^23.3.3",
|
||||
"next": "^12.2.5",
|
||||
"postcss": "^8.4.16",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-tailwindcss": "^0.1.13",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"tailwindcss": "^3.0.18"
|
||||
"tailwindcss": "^3.1.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"electron-is-dev": "^1.1.0",
|
||||
"electron-next": "^3.1.5",
|
||||
"next-themes": "^0.0.15"
|
||||
"electron-is-dev": "^2.0.0",
|
||||
"electron-next": "^3.1.5"
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { ThemeProvider } from "next-themes";
|
||||
import "../styles/globals.css";
|
||||
import Head from "next/head";
|
||||
|
||||
@ -6,15 +5,9 @@ const MyApp = ({ Component, pageProps }) => {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>DeskCut</title>
|
||||
<title>Upscayl</title>
|
||||
</Head>
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="system"
|
||||
enableSystem="true"
|
||||
>
|
||||
<Component {...pageProps} />
|
||||
</ThemeProvider>
|
||||
<Component {...pageProps} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,297 +1,15 @@
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import { checkBox } from "../public/checkbox";
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
const Home = () => {
|
||||
const { theme, setTheme } = useTheme();
|
||||
|
||||
const programRef = useRef(null);
|
||||
const iconRef = useRef(null);
|
||||
|
||||
const [loadedProgram, setLoadedProgram] = useState(false);
|
||||
const [loadedIcon, setLoadedIcon] = useState(false);
|
||||
const [customExec, setCustomExec] = useState(false);
|
||||
const [terminal, setTerminal] = useState(false);
|
||||
const [error, setError] = useState(false);
|
||||
const [darkMode, setDarkMode] = useState(false);
|
||||
const [version, setVersion] = useState("");
|
||||
const [input, setInput] = useState({
|
||||
name: "",
|
||||
comment: "",
|
||||
exec: "",
|
||||
icon: "",
|
||||
terminal: false,
|
||||
});
|
||||
|
||||
console.log(darkMode);
|
||||
|
||||
// Fetch app version
|
||||
useEffect(() => {
|
||||
setVersion(navigator.userAgent.match(/DeskCut\/([\d\.]+\d+)/)[1]);
|
||||
// send(command, payload)
|
||||
window.electron.send("sendMessage", { message: "Hello!" });
|
||||
}, []);
|
||||
|
||||
// Fetching update
|
||||
useEffect(async () => {
|
||||
const updateJson = await fetch(
|
||||
"https://nayamamarshe.github.io/api/deskcut.json",
|
||||
{
|
||||
method: "GET",
|
||||
}
|
||||
).then((res) => res.json());
|
||||
if (updateJson) {
|
||||
if (
|
||||
updateJson.version >
|
||||
navigator.userAgent.match(/DeskCut\/([\d\.]+\d+)/)[1]
|
||||
) {
|
||||
const confirmText = "Update available! Download now?";
|
||||
if (confirm(confirmText) == true) {
|
||||
window.open(
|
||||
"https://github.com/NayamAmarshe/DeskCut/releases/",
|
||||
"_blank"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
const { name, exec, icon } = input;
|
||||
const isValid = Object.values({ name, exec, icon }).every(Boolean);
|
||||
|
||||
if (!isValid) {
|
||||
alert("Please enter the values correctly");
|
||||
} else {
|
||||
window.electron.message(input);
|
||||
alert("Shortcut Successfully Created!");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex h-screen flex-col items-center justify-center bg-slate-50 dark:bg-gray-800">
|
||||
{/* Heading */}
|
||||
<h1 className="pt-5 text-2xl font-bold text-slate-600 dark:text-slate-100">
|
||||
DeskCut
|
||||
</h1>
|
||||
<p className="pb-2 text-sm leading-tight text-slate-400">
|
||||
Shortcut Creator
|
||||
</p>
|
||||
|
||||
<div className="animate absolute top-2 right-2 hover:scale-125 ">
|
||||
<button
|
||||
className="outline-none"
|
||||
onClick={() => {
|
||||
setDarkMode(!darkMode);
|
||||
setTheme(darkMode ? "dark" : "light");
|
||||
console.log(theme);
|
||||
}}
|
||||
>
|
||||
{darkMode ? "🌞" : "🌚"}
|
||||
</button>
|
||||
<div className="h-screen w-screen bg-neutral-900">
|
||||
<div>
|
||||
<input />
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit} className="flex w-96 flex-col gap-5 p-5">
|
||||
{/* Text Inputs */}
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
placeholder="App Name"
|
||||
value={input.name}
|
||||
onChange={(e) =>
|
||||
setInput({
|
||||
...input,
|
||||
name: e.target.value.replace(/[^A-Z0-9]+/gi, " "),
|
||||
})
|
||||
}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
name="comment"
|
||||
placeholder="App Description"
|
||||
value={input.comment}
|
||||
onChange={(e) => setInput({ ...input, comment: e.target.value })}
|
||||
/>
|
||||
|
||||
{/* Terminal Checkbox */}
|
||||
<button
|
||||
type="button"
|
||||
className={`${terminal ? "checkbox-on" : "checkbox-off"} checkbox-bg`}
|
||||
onClick={() => {
|
||||
setTerminal(!terminal);
|
||||
setInput({ ...input, terminal: !input.terminal });
|
||||
}}
|
||||
>
|
||||
<p className="flex-grow">Run in Terminal</p>
|
||||
{!terminal ? (
|
||||
<svg
|
||||
className="align- text-xl"
|
||||
stroke="currentColor"
|
||||
fill="currentColor"
|
||||
strokeWidth="0"
|
||||
viewBox="0 0 24 24"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M7,5C5.897,5,5,5.897,5,7v10c0,1.103,0.897,2,2,2h10c1.103,0,2-0.897,2-2V7c0-1.103-0.897-2-2-2H7z M7,17V7h10l0.002,10H7z"></path>
|
||||
</svg>
|
||||
) : (
|
||||
<svg
|
||||
className="text-xl "
|
||||
stroke="currentColor"
|
||||
fill="currentColor"
|
||||
strokeWidth="0"
|
||||
viewBox="0 0 24 24"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M9 9H15V15H9z"></path>
|
||||
<path d="M19,17V7c0-1.103-0.897-2-2-2H7C5.897,5,5,5.897,5,7v10c0,1.103,0.897,2,2,2h10C18.103,19,19,18.103,19,17z M7,7h10 l0.002,10H7V7z"></path>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
|
||||
{/* Custom Exec Checkbox */}
|
||||
<button
|
||||
type="button"
|
||||
className={`${
|
||||
customExec ? "checkbox-on" : "checkbox-off"
|
||||
} checkbox-bg animate`}
|
||||
onClick={() => setCustomExec(!customExec)}
|
||||
>
|
||||
<p className="flex-grow">Use Custom Icon & Command</p>
|
||||
|
||||
{!customExec ? (
|
||||
<div>
|
||||
<svg
|
||||
className="text-xl"
|
||||
stroke="currentColor"
|
||||
fill="currentColor"
|
||||
strokeWidth="0"
|
||||
viewBox="0 0 24 24"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M7,5C5.897,5,5,5.897,5,7v10c0,1.103,0.897,2,2,2h10c1.103,0,2-0.897,2-2V7c0-1.103-0.897-2-2-2H7z M7,17V7h10l0.002,10H7z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<svg
|
||||
className="text-xl"
|
||||
stroke="currentColor"
|
||||
fill="currentColor"
|
||||
strokeWidth="0"
|
||||
viewBox="0 0 24 24"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M9 9H15V15H9z"></path>
|
||||
<path d="M19,17V7c0-1.103-0.897-2-2-2H7C5.897,5,5,5.897,5,7v10c0,1.103,0.897,2,2,2h10C18.103,19,19,18.103,19,17z M7,7h10 l0.002,10H7V7z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
|
||||
{/* Choose File Buttons */}
|
||||
<div className="animate flex flex-col gap-5">
|
||||
{/* Custom Exec Input */}
|
||||
{customExec ? (
|
||||
<input
|
||||
type="text"
|
||||
name="exec"
|
||||
placeholder="Exec Command"
|
||||
value={input.exec}
|
||||
onChange={(e) => setInput({ ...input, exec: e.target.value })}
|
||||
/>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => programRef.current.click()}
|
||||
className="picker flex flex-col items-center justify-center"
|
||||
>
|
||||
{/* Program Picker */}
|
||||
<p>Choose Program</p>
|
||||
{loadedProgram && (
|
||||
<p className="mt-2 w-80 truncate rounded-lg bg-red-300 p-1 text-slate-700">
|
||||
{programRef?.current?.files[0]?.name}
|
||||
</p>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
{/* Icon Button */}
|
||||
{customExec ? (
|
||||
<input
|
||||
type="text"
|
||||
name="Icon"
|
||||
placeholder="Icon Image Path"
|
||||
value={input.icon}
|
||||
onChange={(e) => setInput({ ...input, icon: e.target.value })}
|
||||
/>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => iconRef.current.click()}
|
||||
className="picker flex flex-col items-center justify-center"
|
||||
>
|
||||
{/* Program Picker */}
|
||||
<p>Choose Icon</p>
|
||||
{loadedIcon && (
|
||||
<p className="mt-2 w-80 truncate rounded-lg bg-red-300 p-1 text-slate-700">
|
||||
{iconRef?.current?.files[0]?.name}
|
||||
</p>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* File Picker */}
|
||||
<input
|
||||
type="file"
|
||||
name="programFile"
|
||||
ref={programRef}
|
||||
className="hidden"
|
||||
onChange={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
console.log(programRef.current);
|
||||
setInput({ ...input, exec: programRef?.current?.files[0]?.path });
|
||||
if (programRef?.current?.files[0]?.path) {
|
||||
setLoadedProgram(true);
|
||||
} else {
|
||||
setLoadedProgram(false);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<input
|
||||
type="file"
|
||||
name="iconFile"
|
||||
ref={iconRef}
|
||||
accept="image/*"
|
||||
className="hidden"
|
||||
onChange={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
console.log(iconRef.current);
|
||||
setInput({ ...input, icon: iconRef?.current?.files[0]?.path });
|
||||
if (iconRef?.current?.files[0]?.path) {
|
||||
setLoadedIcon(true);
|
||||
} else {
|
||||
setLoadedIcon(false);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Submit Button */}
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
<p className="absolute bottom-0 text-slate-200 dark:text-slate-700">
|
||||
v{version}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -3,33 +3,12 @@
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
input,
|
||||
button,
|
||||
.picker {
|
||||
@apply transition-all duration-300 ease-in-out;
|
||||
}
|
||||
input[type="text"] {
|
||||
@apply p-4 ring-offset-0 ring-slate-400 dark:ring-slate-400 focus:ring-2 bg-slate-200 dark:bg-slate-500 placeholder-slate-400 text-slate-700 dark:text-slate-100 rounded-lg outline-none text-center hover:shadow-lg hover:shadow-slate-300 hover:dark:shadow-slate-600 focus:shadow-lg focus:shadow-slate-300 focus:dark:shadow-slate-600 focus:scale-105 hover:scale-105;
|
||||
}
|
||||
button[type="submit"] {
|
||||
@apply outline-none hover:ring-2 ring-green-600 p-4 rounded-lg bg-green-500 text-slate-50 hover:shadow-lg hover:shadow-green-400 hover:dark:shadow-green-700 focus:dark:shadow-green-700 hover:scale-105 ;
|
||||
}
|
||||
.picker {
|
||||
@apply focus:scale-105 outline-none hover:ring-2 ring-red-600 p-4 bg-red-400 rounded-lg text-slate-50 w-full hover:shadow-lg hover:shadow-red-300 hover:dark:shadow-red-700 hover:scale-105 focus:shadow-lg focus:shadow-red-300 focus:dark:shadow-red-700;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.animate {
|
||||
@apply transition-all duration-300 ease-in-out;
|
||||
}
|
||||
.checkbox-bg {
|
||||
@apply hover:ring-2 outline-none cursor-pointer flex flex-row gap-2 items-center p-4 rounded-lg hover:shadow-lg hover:scale-105;
|
||||
}
|
||||
.checkbox-on {
|
||||
@apply bg-yellow-400 ring-yellow-600 shadow-blue-100 hover:shadow-yellow-400 hover:dark:shadow-yellow-600 text-yellow-700;
|
||||
}
|
||||
.checkbox-off {
|
||||
@apply bg-purple-500 hover:dark:shadow-purple-700 ring-purple-600 hover:shadow-purple-400 text-purple-100;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user