@@ -8,47 +8,46 @@ import FlashMessageRender from '@/components/FlashMessageRender';
88import useFlash from '@/plugins/useFlash' ;
99import { SocketEvent , SocketRequest } from '@/components/server/events' ;
1010import Select from '@/components/elements/Select' ;
11+ import useWebsocketEvent from '@/plugins/useWebsocketEvent' ;
12+ import Can from '@/components/elements/Can' ;
13+ import getServerStartup from '@/api/swr/getServerStartup' ;
14+ import InputSpinner from '@/components/elements/InputSpinner' ;
1115
12- const dockerImageList = [
13- { name : 'Java 17' , image : 'ghcr.io/pterodactyl/yolks:java_17' } ,
14- { name : 'Java 16' , image : 'ghcr.io/pterodactyl/yolks:java_16' } ,
15- { name : 'Java 11' , image : 'ghcr.io/pterodactyl/yolks:java_11' } ,
16- { name : 'Java 8' , image : 'ghcr.io/pterodactyl/yolks:java_8' } ,
16+ const MATCH_ERRORS = [
17+ 'minecraft 1.17 requires running the server with java 16 or above' ,
18+ 'minecraft 1.18 requires running the server with java 17 or above' ,
19+ 'java.lang.unsupportedclassversionerror' ,
20+ 'unsupported major.minor version' ,
21+ 'has been compiled by a more recent version of the java runtime' ,
1722] ;
1823
1924const JavaVersionModalFeature = ( ) => {
2025 const [ visible , setVisible ] = useState ( false ) ;
2126 const [ loading , setLoading ] = useState ( false ) ;
22- const [ selectedVersion , setSelectedVersion ] = useState ( 'ghcr.io/pterodactyl/yolks:java_17 ' ) ;
27+ const [ selectedVersion , setSelectedVersion ] = useState ( '' ) ;
2328
2429 const uuid = ServerContext . useStoreState ( state => state . server . data ! . uuid ) ;
2530 const status = ServerContext . useStoreState ( state => state . status . value ) ;
2631 const { clearFlashes, clearAndAddHttpError } = useFlash ( ) ;
27- const { connected , instance } = ServerContext . useStoreState ( state => state . socket ) ;
32+ const { instance } = ServerContext . useStoreState ( state => state . socket ) ;
2833
29- useEffect ( ( ) => {
30- if ( ! connected || ! instance || status === 'running' ) return ;
34+ const { data, isValidating, mutate } = getServerStartup ( uuid , null , { revalidateOnMount : false } ) ;
3135
32- const errors = [
33- 'minecraft 1.17 requires running the server with java 16 or above' ,
34- 'minecraft 1.18 requires running the server with java 17 or above' ,
35- 'java.lang.unsupportedclassversionerror' ,
36- 'unsupported major.minor version' ,
37- 'has been compiled by a more recent version of the java runtime' ,
38- ] ;
36+ useEffect ( ( ) => {
37+ if ( ! visible ) return ;
3938
40- const listener = ( line : string ) => {
41- if ( errors . some ( p => line . toLowerCase ( ) . includes ( p ) ) ) {
42- setVisible ( true ) ;
43- }
44- } ;
39+ mutate ( ) . then ( ( value ) => {
40+ setSelectedVersion ( Object . keys ( value ?. dockerImages || [ ] ) [ 0 ] || '' ) ;
41+ } ) ;
42+ } , [ visible ] ) ;
4543
46- instance . addListener ( SocketEvent . CONSOLE_OUTPUT , listener ) ;
44+ useWebsocketEvent ( SocketEvent . CONSOLE_OUTPUT , ( data ) => {
45+ if ( status === 'running' ) return ;
4746
48- return ( ) => {
49- instance . removeListener ( SocketEvent . CONSOLE_OUTPUT , listener ) ;
50- } ;
51- } , [ connected , instance , status ] ) ;
47+ if ( MATCH_ERRORS . some ( p => data . toLowerCase ( ) . includes ( p . toLowerCase ( ) ) ) ) {
48+ setVisible ( true ) ;
49+ }
50+ } ) ;
5251
5352 const updateJava = ( ) => {
5453 setLoading ( true ) ;
@@ -59,14 +58,9 @@ const JavaVersionModalFeature = () => {
5958 if ( status === 'offline' && instance ) {
6059 instance . send ( SocketRequest . SET_STATE , 'restart' ) ;
6160 }
62-
63- setLoading ( false ) ;
6461 setVisible ( false ) ;
6562 } )
66- . catch ( error => {
67- console . error ( error ) ;
68- clearAndAddHttpError ( { key : 'feature:javaVersion' , error } ) ;
69- } )
63+ . catch ( error => clearAndAddHttpError ( { key : 'feature:javaVersion' , error } ) )
7064 . then ( ( ) => setLoading ( false ) ) ;
7165 } ;
7266
@@ -75,30 +69,43 @@ const JavaVersionModalFeature = () => {
7569 } , [ ] ) ;
7670
7771 return (
78- < Modal visible = { visible } onDismissed = { ( ) => setVisible ( false ) } closeOnBackground = { false } showSpinnerOverlay = { loading } >
72+ < Modal
73+ visible = { visible }
74+ onDismissed = { ( ) => setVisible ( false ) }
75+ closeOnBackground = { false }
76+ showSpinnerOverlay = { loading }
77+ >
7978 < FlashMessageRender key = { 'feature:javaVersion' } css = { tw `mb-4` } />
80- < h2 css = { tw `text-2xl mb-4 text-neutral-100` } > Invalid Java version, update Docker image?</ h2 >
81- < p css = { tw `mt-4` } > This server is unable to start due to the required Java version not being met.</ p >
82- < p css = { tw `mt-4` } > By pressing { '"Update Docker Image"' } below you are acknowledging that the Docker image this server uses will be changed to an image below that has the Java version you are requesting.</ p >
83- < div css = { tw `sm:flex items-center mt-4` } >
84- < p > Please select a Java version from the list below.</ p >
85- < Select
86- onChange = { e => setSelectedVersion ( e . target . value ) }
87- >
88- { dockerImageList . map ( ( key , index ) => {
89- return (
90- < option key = { index } value = { key . image } > { key . name } </ option >
91- ) ;
92- } ) }
93- </ Select >
94- </ div >
95- < div css = { tw `mt-8 sm:flex items-center justify-end` } >
96- < Button isSecondary onClick = { ( ) => setVisible ( false ) } css = { tw `w-full sm:w-auto border-transparent` } >
97- Cancel
79+ < h2 css = { tw `text-2xl mb-4 text-neutral-100` } > Unsupported Java Version</ h2 >
80+ < p css = { tw `mt-4` } >
81+ This server is currently running an unsupported version of Java and cannot be started.
82+ < Can action = { 'startup.docker-image' } >
83+ Please select a supported version from the list below to continue starting the server.
84+ </ Can >
85+ </ p >
86+ < Can action = { 'startup.docker-image' } >
87+ < div css = { tw `mt-4` } >
88+ < InputSpinner visible = { ! data || isValidating } >
89+ < Select disabled = { ! data } onChange = { e => setSelectedVersion ( e . target . value ) } >
90+ { ! data
91+ ? < option disabled />
92+ : Object . keys ( ( data . dockerImages ) ) . map ( ( key ) => (
93+ < option key = { key } value = { data . dockerImages [ key ] } > { key } </ option >
94+ ) )
95+ }
96+ </ Select >
97+ </ InputSpinner >
98+ </ div >
99+ </ Can >
100+ < div css = { tw `mt-8 flex flex-col sm:flex-row justify-end sm:space-x-4 space-y-4 sm:space-y-0` } >
101+ < Button isSecondary onClick = { ( ) => setVisible ( false ) } css = { tw `w-full sm:w-auto` } >
102+ Cancel
98103 </ Button >
99- < Button onClick = { updateJava } css = { tw `mt-4 sm:mt-0 sm:ml-4 w-full sm:w-auto` } >
104+ < Can action = { 'startup.docker-image' } >
105+ < Button onClick = { updateJava } css = { tw `w-full sm:w-auto` } >
100106 Update Docker Image
101- </ Button >
107+ </ Button >
108+ </ Can >
102109 </ div >
103110 </ Modal >
104111 ) ;
0 commit comments