mirror of
https://github.com/ivabus/gui
synced 2025-06-08 00:00:27 +03:00
#191 open terminal
This commit is contained in:
parent
73c9eb843e
commit
4f10b6a867
6 changed files with 73 additions and 6 deletions
|
@ -2,13 +2,11 @@ import windowStateManager from 'electron-window-state';
|
||||||
import { app, BrowserWindow, ipcMain } from 'electron';
|
import { app, BrowserWindow, ipcMain } from 'electron';
|
||||||
import contextMenu from 'electron-context-menu';
|
import contextMenu from 'electron-context-menu';
|
||||||
import serve from 'electron-serve';
|
import serve from 'electron-serve';
|
||||||
import path from 'path';
|
|
||||||
import fs from 'fs';
|
|
||||||
|
|
||||||
import { getInstalledPackages } from './libs/teaDir';
|
import { getInstalledPackages } from './libs/teaDir';
|
||||||
import { readSessionData, writeSessionData } from './libs/auth';
|
import { readSessionData, writeSessionData } from './libs/auth';
|
||||||
import type { Session } from '../src/libs/types';
|
import type { Session } from '../src/libs/types';
|
||||||
import { installPackage } from './libs/cli';
|
import { installPackage, openTerminal } from './libs/cli';
|
||||||
|
|
||||||
// try {
|
// try {
|
||||||
// //@ts-ignore only used in dev should not be packaged inprod
|
// //@ts-ignore only used in dev should not be packaged inprod
|
||||||
|
@ -130,3 +128,16 @@ ipcMain.handle('install-package', async (_, data) => {
|
||||||
const result = await installPackage(data.full_name);
|
const result = await installPackage(data.full_name);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('open-terminal', async (_, data) => {
|
||||||
|
// console.log(data);
|
||||||
|
const { cmd } = data as { cmd: string };
|
||||||
|
try {
|
||||||
|
await openTerminal(cmd);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('elast:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// detect if mac use
|
||||||
|
// https://ss64.com/osx/osascript.html
|
||||||
|
});
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
import { spawn } from 'child_process';
|
import { spawn, exec } from 'child_process';
|
||||||
import { clean } from 'semver';
|
import { clean } from 'semver';
|
||||||
|
import { promisify } from 'util';
|
||||||
|
|
||||||
|
const child_process = require('child_process');
|
||||||
|
|
||||||
|
const execPromise = promisify(exec);
|
||||||
|
|
||||||
export async function installPackage(full_name: string) {
|
export async function installPackage(full_name: string) {
|
||||||
return await new Promise((resolve, reject) => {
|
return await new Promise((resolve, reject) => {
|
||||||
|
@ -27,3 +32,35 @@ export async function installPackage(full_name: string) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function openTerminal(cmd: string) {
|
||||||
|
try {
|
||||||
|
// TODO SECURITY: escape the cmd if possible or create whitelist of acceptable commands
|
||||||
|
return await exec(open(cmd));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('root:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const open = (cmd) => `osascript -e '
|
||||||
|
if application "iTerm" is running then
|
||||||
|
tell application "iTerm"
|
||||||
|
tell current window
|
||||||
|
create tab with default profile
|
||||||
|
tell current session
|
||||||
|
write text "${cmd.replace(/"/g, '\\"')}"
|
||||||
|
end tell
|
||||||
|
end tell
|
||||||
|
end tell
|
||||||
|
else
|
||||||
|
activate application "iTerm"
|
||||||
|
delay 3
|
||||||
|
tell application "iTerm"
|
||||||
|
tell current window
|
||||||
|
tell current session
|
||||||
|
write text "${cmd.replace(/"/g, '\\"')}"
|
||||||
|
end tell
|
||||||
|
end tell
|
||||||
|
end tell
|
||||||
|
end if
|
||||||
|
'`;
|
||||||
|
|
|
@ -83,6 +83,7 @@
|
||||||
"electron-vite": "^1.0.18",
|
"electron-vite": "^1.0.18",
|
||||||
"electron-window-state": "^5.0.3",
|
"electron-window-state": "^5.0.3",
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
|
"iterm-tab": "^0.4.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"lorem-ipsum": "^2.0.8",
|
"lorem-ipsum": "^2.0.8",
|
||||||
"mkdirp": "^2.1.3",
|
"mkdirp": "^2.1.3",
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import '$appcss';
|
import '$appcss';
|
||||||
import Button from '@tea/ui/Button/Button.svelte';
|
import Button from '@tea/ui/Button/Button.svelte';
|
||||||
|
|
||||||
|
const { ipcRenderer } = window.require('electron');
|
||||||
let copyButtonText = 'COPY';
|
let copyButtonText = 'COPY';
|
||||||
const copyValue = `sh <(curl https://tea.xyz)`;
|
const copyValue = `sh <(curl https://tea.xyz)`;
|
||||||
|
|
||||||
|
@ -8,6 +10,10 @@
|
||||||
copyButtonText = 'COPIED!';
|
copyButtonText = 'COPIED!';
|
||||||
navigator.clipboard.writeText(copyValue);
|
navigator.clipboard.writeText(copyValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onInstall = () => {
|
||||||
|
ipcRenderer.invoke('open-terminal', { cmd: copyValue });
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="border-gray mt-4 border bg-black">
|
<section class="border-gray mt-4 border bg-black">
|
||||||
|
@ -20,7 +26,7 @@
|
||||||
<footer class="border-gray flex h-20 border-t text-white">
|
<footer class="border-gray flex h-20 border-t text-white">
|
||||||
<input class="flex-grow bg-black pl-4" disabled value="sh <(curl tea.xyz)>" />
|
<input class="flex-grow bg-black pl-4" disabled value="sh <(curl tea.xyz)>" />
|
||||||
<Button class="w-16 border-0 border-l-2 text-sm" onClick={onCopy}>{copyButtonText}</Button>
|
<Button class="w-16 border-0 border-l-2 text-sm" onClick={onCopy}>{copyButtonText}</Button>
|
||||||
<Button class="w-56 border-0 border-l-2 text-sm" onClick={() => console.log('cli')}
|
<Button class="w-56 border-0 border-l-2 text-sm" onClick={onInstall}
|
||||||
>OPEN IN TERMINAL</Button
|
>OPEN IN TERMINAL</Button
|
||||||
>
|
>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { getPackageBottles } from '@api';
|
import { getPackageBottles } from '@api';
|
||||||
|
|
||||||
|
const { ipcRenderer } = window.require('electron');
|
||||||
|
|
||||||
export let pkg: Package;
|
export let pkg: Package;
|
||||||
let bottles: Bottle[] = [];
|
let bottles: Bottle[] = [];
|
||||||
let packageRating = 0;
|
let packageRating = 0;
|
||||||
|
@ -18,6 +20,10 @@
|
||||||
navigator.clipboard.writeText(copyValue);
|
navigator.clipboard.writeText(copyValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onOpenTerminal = () => {
|
||||||
|
ipcRenderer.invoke('open-terminal', { cmd: `sh <(curl tea.xyz) +${pkg.full_name}` });
|
||||||
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
try {
|
try {
|
||||||
bottles = await getPackageBottles(pkg.full_name);
|
bottles = await getPackageBottles(pkg.full_name);
|
||||||
|
@ -45,7 +51,7 @@
|
||||||
<footer class="border-gray flex h-20 border-t text-white">
|
<footer class="border-gray flex h-20 border-t text-white">
|
||||||
<input class="click-copy flex-grow bg-black pl-4" disabled value={copyValue} />
|
<input class="click-copy flex-grow bg-black pl-4" disabled value={copyValue} />
|
||||||
<Button class="w-16 border-0 border-l-2 text-sm" onClick={onCopy}>{copyButtonText}</Button>
|
<Button class="w-16 border-0 border-l-2 text-sm" onClick={onCopy}>{copyButtonText}</Button>
|
||||||
<Button class="w-56 border-0 border-l-2 text-sm" onClick={() => console.log('cli')}
|
<Button class="w-56 border-0 border-l-2 text-sm" onClick={onOpenTerminal}
|
||||||
>OPEN IN TERMINAL</Button
|
>OPEN IN TERMINAL</Button
|
||||||
>
|
>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -43,6 +43,7 @@ importers:
|
||||||
eslint-config-prettier: ^8.3.0
|
eslint-config-prettier: ^8.3.0
|
||||||
eslint-plugin-svelte3: ^4.0.0
|
eslint-plugin-svelte3: ^4.0.0
|
||||||
fuse.js: ^6.6.2
|
fuse.js: ^6.6.2
|
||||||
|
iterm-tab: ^0.4.0
|
||||||
jsdom: ^21.0.0
|
jsdom: ^21.0.0
|
||||||
lodash: ^4.17.21
|
lodash: ^4.17.21
|
||||||
lorem-ipsum: ^2.0.8
|
lorem-ipsum: ^2.0.8
|
||||||
|
@ -80,6 +81,7 @@ importers:
|
||||||
electron-vite: 1.0.18_vite@4.0.4
|
electron-vite: 1.0.18_vite@4.0.4
|
||||||
electron-window-state: 5.0.3
|
electron-window-state: 5.0.3
|
||||||
fuse.js: 6.6.2
|
fuse.js: 6.6.2
|
||||||
|
iterm-tab: 0.4.0
|
||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
lorem-ipsum: 2.0.8
|
lorem-ipsum: 2.0.8
|
||||||
mkdirp: 2.1.3
|
mkdirp: 2.1.3
|
||||||
|
@ -9134,6 +9136,10 @@ packages:
|
||||||
istanbul-lib-report: 3.0.0
|
istanbul-lib-report: 3.0.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/iterm-tab/0.4.0:
|
||||||
|
resolution: {integrity: sha512-y8qJcWRWhPu8H14AfbsrmPKN+PDMkazcldQYyxYWgqbvsM8XB8aty3Ph2c5FJWNI6mm8D5OTQV9SxJpO9Tihdw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/jake/10.8.5:
|
/jake/10.8.5:
|
||||||
resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==}
|
resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
Loading…
Reference in a new issue