Skip to content

Commit

Permalink
feat: ide awareness during onboarding
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrea Falzetti committed Apr 25, 2022
1 parent 1b88c80 commit 2ae002d
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 189 deletions.
171 changes: 5 additions & 166 deletions components/dashboard/src/settings/Preferences.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,18 @@
* See License-AGPL.txt in the project root for license information.
*/

import { IDEOption, IDEOptions } from "@gitpod/gitpod-protocol/lib/ide-protocol";
import { useContext, useEffect, useState } from "react";
import InfoBox from "../components/InfoBox";
import { useContext, useState } from "react";
import { PageWithSubMenu } from "../components/PageWithSubMenu";
import PillLabel from "../components/PillLabel";
import SelectableCard from "../components/SelectableCard";
import SelectableCardSolid from "../components/SelectableCardSolid";
import Tooltip from "../components/Tooltip";
import { getGitpodService } from "../service/service";
import { ThemeContext } from "../theme-context";
import { UserContext } from "../user-context";
import getSettingsMenu from "./settings-menu";
import { trackEvent } from "../Analytics";
import { PaymentContext } from "../payment-context";
import CheckBox from "../components/CheckBox";
import { IDESettings } from "@gitpod/gitpod-protocol";
import SelectIDE from "./SelectIDE";

type Theme = "light" | "dark" | "system";

Expand Down Expand Up @@ -55,52 +51,6 @@ export default function Preferences() {
};
migrationIDESettings();

const updateUserIDEInfo = async (selectedIde: string, useLatestVersion: boolean) => {
const additionalData = user?.additionalData ?? {};
const settings = additionalData.ideSettings ?? {};
settings.settingVersion = "2.0";
settings.defaultIde = selectedIde;
settings.useLatestVersion = useLatestVersion;
additionalData.ideSettings = settings;
getGitpodService()
.server.trackEvent({
event: "ide_configuration_changed",
properties: settings,
})
.then()
.catch(console.error);
await getGitpodService().server.updateLoggedInUser({ additionalData });
};

const [defaultIde, setDefaultIde] = useState<string>(user?.additionalData?.ideSettings?.defaultIde || "");
const actuallySetDefaultIde = async (value: string) => {
await updateUserIDEInfo(value, useLatestVersion);
setDefaultIde(value);
};

const [useLatestVersion, setUseLatestVersion] = useState<boolean>(
user?.additionalData?.ideSettings?.useLatestVersion ?? false,
);
const actuallySetUseLatestVersion = async (value: boolean) => {
await updateUserIDEInfo(defaultIde, value);
setUseLatestVersion(value);
};

const [ideOptions, setIdeOptions] = useState<IDEOptions | undefined>(undefined);
useEffect(() => {
(async () => {
const ideopts = await getGitpodService().server.getIDEOptions();
// TODO: Compatible with ide-config not deployed, need revert after ide-config deployed
delete ideopts.options["code-latest"];
delete ideopts.options["code-desktop-insiders"];

setIdeOptions(ideopts);
if (!defaultIde || ideopts.options[defaultIde] == null) {
setDefaultIde(ideopts.defaultIde);
}
})();
}, []);

const [theme, setTheme] = useState<Theme>(localStorage.theme || "system");
const actuallySetTheme = (theme: Theme) => {
if (theme === "dark" || theme === "light") {
Expand All @@ -115,8 +65,6 @@ export default function Preferences() {
setTheme(theme);
};

const allIdeOptions = ideOptions && orderedIdeOptions(ideOptions);

const [dotfileRepo, setDotfileRepo] = useState<string>(user?.additionalData?.dotfileRepo || "");
const actuallySetDotfileRepo = async (value: string) => {
const additionalData = user?.additionalData || {};
Expand All @@ -136,80 +84,9 @@ export default function Preferences() {
title="Preferences"
subtitle="Configure user preferences."
>
{ideOptions && (
<>
{allIdeOptions && (
<>
<h3>Editor</h3>
<p className="text-base text-gray-500 dark:text-gray-400">
Choose the editor for opening workspaces.
</p>
<div className="my-4 gap-4 flex flex-wrap max-w-2xl">
{allIdeOptions.map(([id, option]) => {
const selected = defaultIde === id;
const onSelect = () => actuallySetDefaultIde(id);
return renderIdeOption(option, selected, onSelect);
})}
</div>
{ideOptions.options[defaultIde]?.notes && (
<InfoBox className="my-5 max-w-2xl">
<ul>
{ideOptions.options[defaultIde].notes?.map((x, idx) => (
<li className={idx > 0 ? "mt-2" : ""}>{x}</li>
))}
</ul>
</InfoBox>
)}
<p className="text-left w-full text-gray-500">
The <strong>JetBrains desktop IDEs</strong> are currently in beta.{" "}
<a
href="https://github.com/gitpod-io/gitpod/issues/6576"
target="gitpod-feedback-issue"
rel="noopener"
className="gp-link"
>
Send feedback
</a>{" "}
·{" "}
<a
href="https://www.gitpod.io/docs/integrations/jetbrains"
target="_blank"
rel="noopener noreferrer"
className="gp-link"
>
Documentation
</a>
</p>
</>
)}
<CheckBox
title="Latest Release (Unstable)"
desc={
<span>
Use the latest version for each editor.{" "}
<a
className="gp-link"
target="_blank"
href="https://code.visualstudio.com/blogs/2016/02/01/introducing_insiders_build"
>
Insiders
</a>{" "}
for VS Code,{" "}
<a
className="gp-link"
target="_blank"
href="https://www.jetbrains.com/resources/eap/"
>
EAP
</a>{" "}
for JetBrains IDEs.
</span>
}
checked={useLatestVersion}
onChange={(e) => actuallySetUseLatestVersion(e.target.checked)}
/>
</>
)}
<h3>Editor</h3>
<p className="text-base text-gray-500 dark:text-gray-400">Choose the editor for opening workspaces.</p>
<SelectIDE />
<h3 className="mt-12">Theme</h3>
<p className="text-base text-gray-500 dark:text-gray-400">Early bird or night owl? Choose your side.</p>
<div className="mt-4 space-x-4 flex">
Expand Down Expand Up @@ -294,41 +171,3 @@ export default function Preferences() {
</div>
);
}

function orderedIdeOptions(ideOptions: IDEOptions) {
// TODO: Maybe convert orderKey to number before sort?
return Object.entries(ideOptions.options)
.filter(([_, x]) => !x.hidden)
.sort((a, b) => {
const keyA = a[1].orderKey || a[0];
const keyB = b[1].orderKey || b[0];
return keyA.localeCompare(keyB);
});
}

function renderIdeOption(option: IDEOption, selected: boolean, onSelect: () => void): JSX.Element {
const label = option.type === "desktop" ? "" : option.type;
const card = (
<SelectableCardSolid className="w-36 h-40" title={option.title} selected={selected} onClick={onSelect}>
<div className="flex justify-center mt-3">
<img className="w-16 filter-grayscale self-center" src={option.logo} alt="logo" />
</div>
{label ? (
<div
className={`font-semibold text-sm ${
selected ? "text-gray-100 dark:text-gray-600" : "text-gray-600 dark:text-gray-500"
} uppercase mt-2 px-3 py-1 self-center`}
>
{label}
</div>
) : (
<></>
)}
</SelectableCardSolid>
);

if (option.tooltip) {
return <Tooltip content={option.tooltip}>{card}</Tooltip>;
}
return card;
}
Loading

0 comments on commit 2ae002d

Please sign in to comment.