Get available terminals from Terminal module
Before Width: | Height: | Size: 626 B After Width: | Height: | Size: 626 B |
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 132 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@ -4,6 +4,7 @@ import type { ExtensionInfo } from "./ExtensionInfo";
|
||||
import type { OperatingSystem } from "./OperatingSystem";
|
||||
import type { SearchResultItem } from "./SearchResultItem";
|
||||
import type { SearchResultItemAction } from "./SearchResultItemAction";
|
||||
import { Terminal } from "./Terminal";
|
||||
import type { Resources, Translations } from "./Translator";
|
||||
|
||||
/**
|
||||
@ -23,6 +24,7 @@ export type ContextBridge = {
|
||||
fileExists: (filePath: string) => boolean;
|
||||
getAboutUeli: () => AboutUeli;
|
||||
getAvailableExtensions: () => ExtensionInfo[];
|
||||
getAvailableTerminals: () => Terminal[];
|
||||
getEnabledExtensions: () => ExtensionInfo[];
|
||||
getExtension: (extensionId: string) => ExtensionInfo;
|
||||
getExtensionResources: <T extends Translations>() => { extensionId: string; resources: Resources<T> }[];
|
||||
|
5
src/common/Core/Terminal/Terminal.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export type Terminal = {
|
||||
id: string;
|
||||
name: string;
|
||||
assetFilePath: string;
|
||||
};
|
1
src/common/Core/Terminal/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "./Terminal";
|
@ -1,10 +1,14 @@
|
||||
import type { Dependencies } from "@Core/Dependencies";
|
||||
import type { DependencyRegistry } from "@Core/DependencyRegistry";
|
||||
import type { Terminal } from "@common/Core/Terminal";
|
||||
import { TerminalRegistry } from "./TerminalRegistry";
|
||||
import { CommandPrompt, Iterm, MacOsTerminal, Powershell, PowershellCore, Wsl } from "./Terminals";
|
||||
|
||||
export class TerminalModule {
|
||||
public static bootstrap(dependencyRegistry: DependencyRegistry<Dependencies>) {
|
||||
const ipcMain = dependencyRegistry.get("IpcMain");
|
||||
const assetPathResolver = dependencyRegistry.get("AssetPathResolver");
|
||||
|
||||
const terminalRegistry = new TerminalRegistry(dependencyRegistry.get("OperatingSystem"), {
|
||||
Linux: () => [],
|
||||
macOS: () => [
|
||||
@ -20,5 +24,17 @@ export class TerminalModule {
|
||||
});
|
||||
|
||||
dependencyRegistry.register("TerminalRegistry", terminalRegistry);
|
||||
|
||||
ipcMain.on(
|
||||
"getAvailableTerminals",
|
||||
(event) =>
|
||||
(event.returnValue = terminalRegistry.getAll().map(
|
||||
({ terminalId, getAssetFileName, getTerminalName }): Terminal => ({
|
||||
id: terminalId,
|
||||
name: getTerminalName(),
|
||||
assetFilePath: assetPathResolver.getModuleAssetPath("Terminal", getAssetFileName()),
|
||||
}),
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ export class TerminalLauncherExtension implements Extension {
|
||||
|
||||
public getImage(): Image {
|
||||
return {
|
||||
url: `file://${this.assetPathResolver.getExtensionAssetPath(this.id, "windows-terminal.png")}`,
|
||||
url: `file://${this.assetPathResolver.getModuleAssetPath("Terminal", "windows-terminal.png")}`,
|
||||
};
|
||||
}
|
||||
|
||||
@ -117,8 +117,8 @@ export class TerminalLauncherExtension implements Extension {
|
||||
}
|
||||
|
||||
public getAssetFilePath(terminalId: string): string {
|
||||
return this.assetPathResolver.getExtensionAssetPath(
|
||||
this.id,
|
||||
return this.assetPathResolver.getModuleAssetPath(
|
||||
"Terminal",
|
||||
this.terminalRegistry.getById(terminalId).getAssetFileName(),
|
||||
);
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ export class WorkflowExtension implements Extension {
|
||||
type: "Type",
|
||||
"type.OpenFile": "Open file",
|
||||
"type.OpenUrl": "Open URL",
|
||||
"type.OpenTerminal": "Open terminal",
|
||||
"type.ExecuteCommand": "Execute command",
|
||||
newAction: "New Action",
|
||||
actionName: "Action name",
|
||||
@ -121,6 +122,7 @@ export class WorkflowExtension implements Extension {
|
||||
type: "Typ",
|
||||
"type.OpenFile": "Datei öffnen",
|
||||
"type.OpenUrl": "URL öffnen",
|
||||
"type.OpenTerminal": "Terminal öffnen",
|
||||
"type.ExecuteCommand": "Befehl ausführen",
|
||||
newAction: "Neue Aktion",
|
||||
actionName: "Name der Aktion",
|
||||
|
@ -16,6 +16,7 @@ const contextBridgeImplementation: ContextBridge = {
|
||||
fileExists: (filePath: string) => ipcRenderer.sendSync("fileExists", { filePath }),
|
||||
getAboutUeli: () => ipcRenderer.sendSync("getAboutUeli"),
|
||||
getAvailableExtensions: () => ipcRenderer.sendSync("getAvailableExtensions"),
|
||||
getAvailableTerminals: () => ipcRenderer.sendSync("getAvailableTerminals"),
|
||||
getEnabledExtensions: () => ipcRenderer.sendSync("getEnabledExtensions"),
|
||||
getExtension: (extensionId) => ipcRenderer.sendSync("getExtension", { extensionId }),
|
||||
getExtensionResources: () => ipcRenderer.sendSync("getExtensionResources"),
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { useContextBridge, useExtensionSetting } from "@Core/Hooks";
|
||||
import { Section } from "@Core/Settings/Section";
|
||||
import { SectionList } from "@Core/Settings/SectionList";
|
||||
import type { OperatingSystem } from "@common/Core";
|
||||
import { Dropdown, Field, Input, Option } from "@fluentui/react-components";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
@ -12,12 +11,6 @@ export const TerminalLauncherSettings = () => {
|
||||
const extensionId = "TerminalLauncher";
|
||||
const ns = "extension[TerminalLauncher]";
|
||||
|
||||
const options: Record<OperatingSystem, string[]> = {
|
||||
macOS: ["Terminal", "iTerm"],
|
||||
Windows: ["Command Prompt", "Powershell", "Powershell Core", "WSL"],
|
||||
Linux: [],
|
||||
};
|
||||
|
||||
const { value: prefix, updateValue: setPrefix } = useExtensionSetting<string>({ extensionId, key: "prefix" });
|
||||
|
||||
const { value: terminalIds, updateValue: setTerminalIds } = useExtensionSetting<string[]>({
|
||||
@ -25,6 +18,8 @@ export const TerminalLauncherSettings = () => {
|
||||
key: "terminalIds",
|
||||
});
|
||||
|
||||
const availableTerminals = contextBridge.getAvailableTerminals();
|
||||
|
||||
return (
|
||||
<SectionList>
|
||||
<Section>
|
||||
@ -41,14 +36,10 @@ export const TerminalLauncherSettings = () => {
|
||||
multiselect
|
||||
onOptionSelect={(_, { selectedOptions }) => setTerminalIds(selectedOptions)}
|
||||
>
|
||||
{options[contextBridge.getOperatingSystem()].map((option) => (
|
||||
<Option key={option} value={option} text={option}>
|
||||
<img
|
||||
src={`file://${contextBridge.getExtensionAssetFilePath(extensionId, option)}`}
|
||||
width={24}
|
||||
alt={option}
|
||||
/>
|
||||
<span>{option}</span>
|
||||
{availableTerminals.map((terminal) => (
|
||||
<Option key={terminal.id} value={terminal.id} text={terminal.name}>
|
||||
<img src={`file://${terminal.assetFilePath}`} width={24} alt={terminal.name} />
|
||||
<span>{terminal.name}</span>
|
||||
</Option>
|
||||
))}
|
||||
</Dropdown>
|
||||
|
@ -1,15 +1,9 @@
|
||||
import { useContextBridge } from "@Core/Hooks";
|
||||
import { OperatingSystem } from "@common/Core";
|
||||
import type { OpenTerminalActionArgs } from "@common/Extensions/Workflow";
|
||||
import { Dropdown, Field, Input, Option } from "@fluentui/react-components";
|
||||
import type { NewActionTypeProps } from "./NewActionTypeProps";
|
||||
|
||||
export const NewActionOpenTerminal = ({ args, setArgs }: NewActionTypeProps) => {
|
||||
console.log({
|
||||
m: "render",
|
||||
args,
|
||||
});
|
||||
|
||||
const { contextBridge } = useContextBridge();
|
||||
|
||||
const { terminalId, command } = args as OpenTerminalActionArgs;
|
||||
@ -18,31 +12,34 @@ export const NewActionOpenTerminal = ({ args, setArgs }: NewActionTypeProps) =>
|
||||
|
||||
const setCommand = (newCommand: string) => setArgs({ terminalId, command: newCommand });
|
||||
|
||||
const terminalIds: Record<OperatingSystem, string[]> = {
|
||||
Linux: [],
|
||||
macOS: ["Terminal", "iTerm"],
|
||||
Windows: ["Command Prompt", "PowerShell", "Windows Terminal"],
|
||||
};
|
||||
const defaultTerminalId = contextBridge.getAvailableTerminals()[0]?.id;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Field label="Terminal">
|
||||
<Dropdown
|
||||
selectedOptions={[terminalId]}
|
||||
selectedOptions={[terminalId || defaultTerminalId]}
|
||||
value={terminalId}
|
||||
placeholder="Select a terminal"
|
||||
onOptionSelect={(_, { optionValue }) => optionValue && setTerminalId(optionValue)}
|
||||
disabled={!terminalId}
|
||||
size="small"
|
||||
>
|
||||
{terminalIds[contextBridge.getOperatingSystem()].map((terminalId) => (
|
||||
<Option key={terminalId} value={terminalId}>
|
||||
{terminalId}
|
||||
{contextBridge.getAvailableTerminals().map(({ id, name, assetFilePath }) => (
|
||||
<Option key={id} value={id} text={name}>
|
||||
<img src={`file://${assetFilePath}`} alt={name} width={16} />
|
||||
<span>{name}</span>
|
||||
</Option>
|
||||
))}
|
||||
</Dropdown>
|
||||
</Field>
|
||||
<Field label="Command">
|
||||
<Input value={command} onChange={(_, { value }) => setCommand(value)} placeholder="Enter a command" />
|
||||
<Input
|
||||
value={command}
|
||||
onChange={(_, { value }) => setCommand(value)}
|
||||
placeholder="Enter a command"
|
||||
size="small"
|
||||
/>
|
||||
</Field>
|
||||
</>
|
||||
);
|
||||
|