44 * See License-AGPL.txt in the project root for license information.
55 */
66
7- import { IDEOption , IDEOptions } from "@gitpod/gitpod-protocol/lib/ide-protocol" ;
8- import { useContext , useEffect , useState } from "react" ;
9- import InfoBox from "../components/InfoBox" ;
7+ import { useContext , useState } from "react" ;
108import { PageWithSubMenu } from "../components/PageWithSubMenu" ;
119import PillLabel from "../components/PillLabel" ;
1210import SelectableCard from "../components/SelectableCard" ;
13- import SelectableCardSolid from "../components/SelectableCardSolid" ;
14- import Tooltip from "../components/Tooltip" ;
1511import { getGitpodService } from "../service/service" ;
1612import { ThemeContext } from "../theme-context" ;
1713import { UserContext } from "../user-context" ;
1814import getSettingsMenu from "./settings-menu" ;
1915import { trackEvent } from "../Analytics" ;
2016import { PaymentContext } from "../payment-context" ;
21- import CheckBox from "../components/CheckBox" ;
22- import { IDESettings } from "@gitpod/gitpod-protocol" ;
17+ import SelectIDE from "./SelectIDE" ;
2318
2419type Theme = "light" | "dark" | "system" ;
2520
@@ -28,79 +23,6 @@ export default function Preferences() {
2823 const { showPaymentUI } = useContext ( PaymentContext ) ;
2924 const { setIsDark } = useContext ( ThemeContext ) ;
3025
31- const migrationIDESettings = ( ) => {
32- if ( ! user ?. additionalData ?. ideSettings || user . additionalData . ideSettings . settingVersion === "2.0" ) {
33- return ;
34- }
35- const newIDESettings : IDESettings = {
36- settingVersion : "2.0" ,
37- } ;
38- const ideSettings = user . additionalData . ideSettings ;
39- if ( ideSettings . useDesktopIde ) {
40- if ( ideSettings . defaultDesktopIde === "code-desktop" ) {
41- newIDESettings . defaultIde = "code-desktop" ;
42- } else if ( ideSettings . defaultDesktopIde === "code-desktop-insiders" ) {
43- newIDESettings . defaultIde = "code-desktop" ;
44- newIDESettings . useLatestVersion = true ;
45- } else {
46- newIDESettings . defaultIde = ideSettings . defaultDesktopIde ;
47- newIDESettings . useLatestVersion = ideSettings . useLatestVersion ;
48- }
49- } else {
50- const useLatest = ideSettings . defaultIde === "code-latest" ;
51- newIDESettings . defaultIde = "code" ;
52- newIDESettings . useLatestVersion = useLatest ;
53- }
54- user . additionalData . ideSettings = newIDESettings ;
55- } ;
56- migrationIDESettings ( ) ;
57-
58- const updateUserIDEInfo = async ( selectedIde : string , useLatestVersion : boolean ) => {
59- const additionalData = user ?. additionalData ?? { } ;
60- const settings = additionalData . ideSettings ?? { } ;
61- settings . settingVersion = "2.0" ;
62- settings . defaultIde = selectedIde ;
63- settings . useLatestVersion = useLatestVersion ;
64- additionalData . ideSettings = settings ;
65- getGitpodService ( )
66- . server . trackEvent ( {
67- event : "ide_configuration_changed" ,
68- properties : settings ,
69- } )
70- . then ( )
71- . catch ( console . error ) ;
72- await getGitpodService ( ) . server . updateLoggedInUser ( { additionalData } ) ;
73- } ;
74-
75- const [ defaultIde , setDefaultIde ] = useState < string > ( user ?. additionalData ?. ideSettings ?. defaultIde || "" ) ;
76- const actuallySetDefaultIde = async ( value : string ) => {
77- await updateUserIDEInfo ( value , useLatestVersion ) ;
78- setDefaultIde ( value ) ;
79- } ;
80-
81- const [ useLatestVersion , setUseLatestVersion ] = useState < boolean > (
82- user ?. additionalData ?. ideSettings ?. useLatestVersion ?? false ,
83- ) ;
84- const actuallySetUseLatestVersion = async ( value : boolean ) => {
85- await updateUserIDEInfo ( defaultIde , value ) ;
86- setUseLatestVersion ( value ) ;
87- } ;
88-
89- const [ ideOptions , setIdeOptions ] = useState < IDEOptions | undefined > ( undefined ) ;
90- useEffect ( ( ) => {
91- ( async ( ) => {
92- const ideopts = await getGitpodService ( ) . server . getIDEOptions ( ) ;
93- // TODO: Compatible with ide-config not deployed, need revert after ide-config deployed
94- delete ideopts . options [ "code-latest" ] ;
95- delete ideopts . options [ "code-desktop-insiders" ] ;
96-
97- setIdeOptions ( ideopts ) ;
98- if ( ! defaultIde || ideopts . options [ defaultIde ] == null ) {
99- setDefaultIde ( ideopts . defaultIde ) ;
100- }
101- } ) ( ) ;
102- } , [ ] ) ;
103-
10426 const [ theme , setTheme ] = useState < Theme > ( localStorage . theme || "system" ) ;
10527 const actuallySetTheme = ( theme : Theme ) => {
10628 if ( theme === "dark" || theme === "light" ) {
@@ -115,8 +37,6 @@ export default function Preferences() {
11537 setTheme ( theme ) ;
11638 } ;
11739
118- const allIdeOptions = ideOptions && orderedIdeOptions ( ideOptions ) ;
119-
12040 const [ dotfileRepo , setDotfileRepo ] = useState < string > ( user ?. additionalData ?. dotfileRepo || "" ) ;
12141 const actuallySetDotfileRepo = async ( value : string ) => {
12242 const additionalData = user ?. additionalData || { } ;
@@ -136,80 +56,9 @@ export default function Preferences() {
13656 title = "Preferences"
13757 subtitle = "Configure user preferences."
13858 >
139- { ideOptions && (
140- < >
141- { allIdeOptions && (
142- < >
143- < h3 > Editor</ h3 >
144- < p className = "text-base text-gray-500 dark:text-gray-400" >
145- Choose the editor for opening workspaces.
146- </ p >
147- < div className = "my-4 gap-4 flex flex-wrap max-w-2xl" >
148- { allIdeOptions . map ( ( [ id , option ] ) => {
149- const selected = defaultIde === id ;
150- const onSelect = ( ) => actuallySetDefaultIde ( id ) ;
151- return renderIdeOption ( option , selected , onSelect ) ;
152- } ) }
153- </ div >
154- { ideOptions . options [ defaultIde ] ?. notes && (
155- < InfoBox className = "my-5 max-w-2xl" >
156- < ul >
157- { ideOptions . options [ defaultIde ] . notes ?. map ( ( x , idx ) => (
158- < li className = { idx > 0 ? "mt-2" : "" } > { x } </ li >
159- ) ) }
160- </ ul >
161- </ InfoBox >
162- ) }
163- < p className = "text-left w-full text-gray-500" >
164- The < strong > JetBrains desktop IDEs</ strong > are currently in beta.{ " " }
165- < a
166- href = "https://github.com/gitpod-io/gitpod/issues/6576"
167- target = "gitpod-feedback-issue"
168- rel = "noopener"
169- className = "gp-link"
170- >
171- Send feedback
172- </ a > { " " }
173- ·{ " " }
174- < a
175- href = "https://www.gitpod.io/docs/integrations/jetbrains"
176- target = "_blank"
177- rel = "noopener noreferrer"
178- className = "gp-link"
179- >
180- Documentation
181- </ a >
182- </ p >
183- </ >
184- ) }
185- < CheckBox
186- title = "Latest Release (Unstable)"
187- desc = {
188- < span >
189- Use the latest version for each editor.{ " " }
190- < a
191- className = "gp-link"
192- target = "_blank"
193- href = "https://code.visualstudio.com/blogs/2016/02/01/introducing_insiders_build"
194- >
195- Insiders
196- </ a > { " " }
197- for VS Code,{ " " }
198- < a
199- className = "gp-link"
200- target = "_blank"
201- href = "https://www.jetbrains.com/resources/eap/"
202- >
203- EAP
204- </ a > { " " }
205- for JetBrains IDEs.
206- </ span >
207- }
208- checked = { useLatestVersion }
209- onChange = { ( e ) => actuallySetUseLatestVersion ( e . target . checked ) }
210- />
211- </ >
212- ) }
59+ < h3 > Editor</ h3 >
60+ < p className = "text-base text-gray-500 dark:text-gray-400" > Choose the editor for opening workspaces.</ p >
61+ < SelectIDE />
21362 < h3 className = "mt-12" > Theme</ h3 >
21463 < p className = "text-base text-gray-500 dark:text-gray-400" > Early bird or night owl? Choose your side.</ p >
21564 < div className = "mt-4 space-x-4 flex" >
@@ -294,41 +143,3 @@ export default function Preferences() {
294143 </ div >
295144 ) ;
296145}
297-
298- function orderedIdeOptions ( ideOptions : IDEOptions ) {
299- // TODO: Maybe convert orderKey to number before sort?
300- return Object . entries ( ideOptions . options )
301- . filter ( ( [ _ , x ] ) => ! x . hidden )
302- . sort ( ( a , b ) => {
303- const keyA = a [ 1 ] . orderKey || a [ 0 ] ;
304- const keyB = b [ 1 ] . orderKey || b [ 0 ] ;
305- return keyA . localeCompare ( keyB ) ;
306- } ) ;
307- }
308-
309- function renderIdeOption ( option : IDEOption , selected : boolean , onSelect : ( ) => void ) : JSX . Element {
310- const label = option . type === "desktop" ? "" : option . type ;
311- const card = (
312- < SelectableCardSolid className = "w-36 h-40" title = { option . title } selected = { selected } onClick = { onSelect } >
313- < div className = "flex justify-center mt-3" >
314- < img className = "w-16 filter-grayscale self-center" src = { option . logo } alt = "logo" />
315- </ div >
316- { label ? (
317- < div
318- className = { `font-semibold text-sm ${
319- selected ? "text-gray-100 dark:text-gray-600" : "text-gray-600 dark:text-gray-500"
320- } uppercase mt-2 px-3 py-1 self-center`}
321- >
322- { label }
323- </ div >
324- ) : (
325- < > </ >
326- ) }
327- </ SelectableCardSolid >
328- ) ;
329-
330- if ( option . tooltip ) {
331- return < Tooltip content = { option . tooltip } > { card } </ Tooltip > ;
332- }
333- return card ;
334- }
0 commit comments