1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Introduce competition for terminal preference tab

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
Janne Savolainen 2022-10-13 14:11:48 +03:00
parent aa90e8e7d2
commit 943bc6db77
No known key found for this signature in database
GPG Key ID: 8C6CFB2FFFE8F68A
13 changed files with 438 additions and 0 deletions

View File

@ -0,0 +1,23 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { preferenceItemInjectionToken } from "../../preference-item-injection-token";
import { CopyPasteFromTerminal } from "./copy-paste-from-terminal";
const copyPasteFromTerminalPreferenceItemInjectable = getInjectable({
id: "copy-paste-from-terminal-preference-item",
instantiate: () => ({
kind: "item" as const,
id: "copy-paste-from-terminal-preference-item",
parentId: "terminal-page",
orderNumber: 20,
Component: CopyPasteFromTerminal,
}),
injectionToken: preferenceItemInjectionToken,
});
export default copyPasteFromTerminalPreferenceItemInjectable;

View File

@ -0,0 +1,42 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import React from "react";
import { SubTitle } from "../../../../../../renderer/components/layout/sub-title";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { UserStore } from "../../../../../../common/user-store";
import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable";
import { observer } from "mobx-react";
import { Switch } from "../../../../../../renderer/components/switch";
interface Dependencies {
userStore: UserStore;
}
const NonInjectedCopyPasteFromTerminal = observer(
({ userStore }: Dependencies) => {
return (
<div>
<SubTitle title="Terminal copy & paste" />
<Switch
checked={userStore.terminalCopyOnSelect}
onChange={() => userStore.terminalCopyOnSelect = !userStore.terminalCopyOnSelect}
>
Copy on select and paste on right-click
</Switch>
</div>
);
},
);
export const CopyPasteFromTerminal = withInjectables<Dependencies>(
NonInjectedCopyPasteFromTerminal,
{
getProps: (di) => ({
userStore: di.inject(userStoreInjectable),
}),
},
);

View File

@ -0,0 +1,23 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { preferenceItemInjectionToken } from "../../preference-item-injection-token";
import { TerminalFontFamily } from "./terminal-font-family";
const terminalFontFamilyPreferenceItemInjectable = getInjectable({
id: "terminal-font-family-preference-item",
instantiate: () => ({
kind: "item" as const,
id: "terminal-font-family-preference-item",
parentId: "terminal-page",
orderNumber: 40,
Component: TerminalFontFamily,
}),
injectionToken: preferenceItemInjectionToken,
});
export default terminalFontFamilyPreferenceItemInjectable;

View File

@ -0,0 +1,70 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import React from "react";
import { SubTitle } from "../../../../../../renderer/components/layout/sub-title";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { UserStore } from "../../../../../../common/user-store";
import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable";
import { observer } from "mobx-react";
import type { SelectOption } from "../../../../../../renderer/components/select";
import { Select } from "../../../../../../renderer/components/select";
import type { Logger } from "../../../../../../common/logger";
import { action } from "mobx";
import loggerInjectable from "../../../../../../common/logger.injectable";
interface Dependencies {
userStore: UserStore;
logger: Logger;
}
const NonInjectedTerminalFontFamily = observer(
({ userStore, logger }: Dependencies) => {
// fonts must be declared in `fonts.scss` and at `template.html` (if early-preloading required)
const supportedCustomFonts: SelectOption<string>[] = [
"RobotoMono", "Anonymous Pro", "IBM Plex Mono", "JetBrains Mono", "Red Hat Mono",
"Source Code Pro", "Space Mono", "Ubuntu Mono",
].map(customFont => {
const { fontFamily, fontSize } = userStore.terminalConfig;
return {
label: <span style={{ fontFamily: customFont, fontSize }}>{customFont}</span>,
value: customFont,
isSelected: fontFamily === customFont,
};
});
const onFontFamilyChange = action(({ value: fontFamily }: SelectOption<string>) => {
logger.info(`setting terminal font to ${fontFamily}`);
userStore.terminalConfig.fontFamily = fontFamily; // save to external storage
});
return (
<section>
<SubTitle title="Font family" />
<Select
themeName="lens"
controlShouldRenderValue
value={userStore.terminalConfig.fontFamily}
options={supportedCustomFonts}
onChange={onFontFamilyChange as any}
/>
</section>
);
},
);
export const TerminalFontFamily = withInjectables<Dependencies>(
NonInjectedTerminalFontFamily,
{
getProps: (di) => ({
userStore: di.inject(userStoreInjectable),
logger: di.inject(loggerInjectable),
}),
},
);

View File

@ -0,0 +1,23 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { preferenceItemInjectionToken } from "../../preference-item-injection-token";
import { TerminalFontSize } from "./terminal-font-size";
const terminalFontSizePreferenceItemInjectable = getInjectable({
id: "terminal-font-size-preference-item",
instantiate: () => ({
kind: "item" as const,
id: "terminal-font-size-preference-item",
parentId: "terminal-page",
orderNumber: 30,
Component: TerminalFontSize,
}),
injectionToken: preferenceItemInjectionToken,
});
export default terminalFontSizePreferenceItemInjectable;

View File

@ -0,0 +1,44 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import React from "react";
import { SubTitle } from "../../../../../../renderer/components/layout/sub-title";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { UserStore } from "../../../../../../common/user-store";
import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable";
import { observer } from "mobx-react";
import { Input } from "../../../../../../renderer/components/input";
interface Dependencies {
userStore: UserStore;
}
const NonInjectedTerminalFontSize = observer(
({ userStore }: Dependencies) => {
return (
<div>
<SubTitle title="Font size" />
<Input
theme="round-black"
type="number"
min={10}
max={50}
defaultValue={userStore.terminalConfig.fontSize.toString()}
onChange={(value) => userStore.terminalConfig.fontSize = Number(value)}
/>
</div>
);
},
);
export const TerminalFontSize = withInjectables<Dependencies>(
NonInjectedTerminalFontSize,
{
getProps: (di) => ({
userStore: di.inject(userStoreInjectable),
}),
},
);

View File

@ -0,0 +1,25 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { preferenceItemInjectionToken } from "../preference-item-injection-token";
import { TerminalPage } from "./terminal-page";
import { HorizontalLine } from "../../../../../renderer/components/+preferences/horizontal-line/horizontal-line";
const terminalPagePreferenceItemInjectable = getInjectable({
id: "terminal-preference-page",
instantiate: () => ({
kind: "page" as const,
id: "terminal-page",
parentId: "terminal-tab",
orderNumber: 0,
Component: TerminalPage,
childrenSeparator: HorizontalLine,
}),
injectionToken: preferenceItemInjectionToken,
});
export default terminalPagePreferenceItemInjectable;

View File

@ -0,0 +1,14 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import React from "react";
import type { PreferenceItemComponent } from "../preference-item-injection-token";
export const TerminalPage: PreferenceItemComponent = ({ children }) => (
<div>
<h2 data-testid="terminal-header">Terminal</h2>
{children}
</div>
);

View File

@ -0,0 +1,24 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { preferenceItemInjectionToken } from "../preference-item-injection-token";
const terminalPreferenceTabInjectable = getInjectable({
id: "terminal-preference-tab",
instantiate: () => ({
kind: "tab" as const,
id: "terminal-tab",
pathId: "terminal",
parentId: "preference-tabs" as const,
testId: "terminal-preferences-page",
label: "Terminal",
orderNumber: 20,
}),
injectionToken: preferenceItemInjectionToken,
});
export default terminalPreferenceTabInjectable;

View File

@ -0,0 +1,23 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { preferenceItemInjectionToken } from "../../preference-item-injection-token";
import { TerminalShellPath } from "./terminal-shell-path";
const terminalShellPathPreferenceItemInjectable = getInjectable({
id: "terminal-shell-path-preference-item",
instantiate: () => ({
kind: "item" as const,
id: "terminal-shell-path",
parentId: "terminal-page",
orderNumber: 10,
Component: TerminalShellPath,
}),
injectionToken: preferenceItemInjectionToken,
});
export default terminalShellPathPreferenceItemInjectable;

View File

@ -0,0 +1,46 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import React from "react";
import { SubTitle } from "../../../../../../renderer/components/layout/sub-title";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { UserStore } from "../../../../../../common/user-store";
import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable";
import { observer } from "mobx-react";
import { Input } from "../../../../../../renderer/components/input";
import defaultShellInjectable from "../../../../../../renderer/components/+preferences/default-shell.injectable";
interface Dependencies {
userStore: UserStore;
defaultShell: string;
}
const NonInjectedTerminalShellPath = observer(
({ userStore, defaultShell }: Dependencies) => {
return (
<div>
<SubTitle title="Terminal Shell Path" />
<Input
theme="round-black"
placeholder={defaultShell}
value={userStore.shell ?? ""}
onChange={(value) => userStore.shell = value}
/>
</div>
);
},
);
export const TerminalShellPath = withInjectables<Dependencies>(
NonInjectedTerminalShellPath,
{
getProps: (di) => ({
userStore: di.inject(userStoreInjectable),
defaultShell: di.inject(defaultShellInjectable),
}),
},
);

View File

@ -0,0 +1,23 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { preferenceItemInjectionToken } from "../../preference-item-injection-token";
import { TerminalTheme } from "./terminal-theme";
const terminalThemePreferenceItemInjectable = getInjectable({
id: "terminal-theme",
instantiate: () => ({
kind: "item" as const,
id: "terminal-theme",
parentId: "terminal-page",
orderNumber: 30,
Component: TerminalTheme,
}),
injectionToken: preferenceItemInjectionToken,
});
export default terminalThemePreferenceItemInjectable;

View File

@ -0,0 +1,58 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import React from "react";
import { SubTitle } from "../../../../../../renderer/components/layout/sub-title";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { UserStore } from "../../../../../../common/user-store";
import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable";
import { observer } from "mobx-react";
import { Select } from "../../../../../../renderer/components/select";
import themeStoreInjectable from "../../../../../../renderer/themes/store.injectable";
import type { ThemeStore } from "../../../../../../renderer/themes/store";
interface Dependencies {
userStore: UserStore;
themeStore: ThemeStore;
}
const NonInjectedTerminalTheme = observer(
({ userStore, themeStore }: Dependencies) => {
const themeOptions = [
{
value: "", // TODO: replace with a sentinal value that isn't string (and serialize it differently)
label: "Match Lens Theme",
},
...Array.from(themeStore.themes, ([themeId, { name }]) => ({
value: themeId,
label: name,
})),
];
return (
<div>
<SubTitle title="Terminal theme" />
<Select
id="terminal-theme-input"
themeName="lens"
options={themeOptions}
value={userStore.terminalTheme}
onChange={option => userStore.terminalTheme = option?.value ?? ""}
/>
</div>
);
},
);
export const TerminalTheme = withInjectables<Dependencies>(
NonInjectedTerminalTheme,
{
getProps: (di) => ({
userStore: di.inject(userStoreInjectable),
themeStore: di.inject(themeStoreInjectable),
}),
},
);