@@ -7,12 +7,15 @@ import { WebsocketProvider } from "y-websocket";
7
7
import { useAuth } from "./AuthContext" ;
8
8
import { toast } from "react-toastify" ;
9
9
import { COLLABORATION_AWARENESS_KEYS , COLLABORATION_YMAP_KEYS } from "presentation/utils/constants" ;
10
+ import PistonClient from "data/piston/PistonClient" ;
11
+ import { Language } from "domain/entities/Language" ;
10
12
11
13
interface CollaborationContextType {
12
14
initialiseEditor : ( roomId : string , editor : any , monaco : Monaco ) => void ;
13
- selectedLanguage : string ;
14
- languages : any ;
15
- handleChangeLanguage : ( lang : string ) => void ;
15
+ selectedLanguage : Language ;
16
+ languages : Language [ ] ;
17
+ handleChangeLanguage : ( lang : Language ) => void ;
18
+ handleExecuteCode : ( ) => void ;
16
19
}
17
20
const CollaborationContext = createContext < CollaborationContextType | undefined > ( undefined ) ;
18
21
@@ -23,50 +26,56 @@ export const CollaborationProvider: React.FC<{ children: ReactNode }> = ({ child
23
26
const { USERNAME } = COLLABORATION_AWARENESS_KEYS ;
24
27
const { SELECTED_LANGUAGE } = COLLABORATION_YMAP_KEYS ;
25
28
26
- const [ selectedLanguage , setSelectedLanguage ] = useState < string > ( "javascript" ) ;
27
- const [ languages , setLanguages ] = useState < { label : string ; value : string } [ ] > ( [ ] ) ;
29
+ const [ selectedLanguage , setSelectedLanguage ] = useState < Language > ( {
30
+ language : "javascript" ,
31
+ version : "" ,
32
+ alias : "Javascript"
33
+ } ) ;
34
+ const [ languages , setLanguages ] = useState < Language [ ] > ( [ ] ) ;
28
35
29
36
const editorRef = useRef < monaco . editor . IStandaloneCodeEditor | null > ( null ) ;
30
37
const monacoRef = useRef < Monaco | null > ( null ) ;
31
38
const bindingRef = useRef < MonacoBinding | null > ( null ) ;
32
39
const providerRef = useRef < WebsocketProvider | null > ( null ) ;
33
40
const ydocRef = useRef < Y . Doc | null > ( null ) ;
34
- const yMapRef = useRef < Y . Map < string > | null > ( null ) ;
41
+ const yMapRef = useRef < Y . Map < any > | null > ( null ) ;
35
42
36
- const initialiseEditor = ( roomId : string , editor : monaco . editor . IStandaloneCodeEditor , monaco : Monaco ) => {
43
+ const initialiseEditor = async ( roomId : string , editor : monaco . editor . IStandaloneCodeEditor , monaco : Monaco ) => {
37
44
editorRef . current = editor ;
38
45
monacoRef . current = monaco ;
39
46
40
- initialiseLanguages ( monaco ) ;
47
+ await initialiseLanguages ( monaco ) ;
41
48
const { yDoc, provider, yMap } = initialiseYdoc ( roomId ) ;
42
49
bindEditorToDoc ( editor , yDoc , provider ) ;
43
50
setUpObserver ( yMap ) ;
44
51
setUpConnectionAwareness ( provider ) ;
45
52
} ;
46
53
47
- const initialiseLanguages = ( monaco : Monaco ) => {
54
+ const initialiseLanguages = async ( monaco : Monaco ) => {
48
55
const allLanguages = monaco . languages . getLanguages ( ) ;
49
-
50
- // TODO: Filter all the useless ones like HTML
56
+ const pistonLanguageVersions = await PistonClient . getLanguageVersions ( ) ;
51
57
setLanguages (
52
- allLanguages . map ( ( lang ) => ( {
53
- label : lang . aliases && lang . aliases . length > 0 ? lang . aliases [ 0 ] : lang . id ,
54
- value : lang . id
55
- } ) )
58
+ allLanguages
59
+ . filter ( ( lang ) => pistonLanguageVersions . some ( ( pistonLang : any ) => pistonLang . language === lang . id ) )
60
+ . map ( ( lang ) => ( {
61
+ alias : lang . aliases && lang . aliases . length > 0 ? lang . aliases [ 0 ] : lang . id ,
62
+ language : lang . id ,
63
+ version : pistonLanguageVersions . find ( ( pistonLang : any ) => pistonLang . language === lang . id ) ?. version
64
+ } ) )
56
65
) ;
57
66
} ;
58
67
59
- const initialiseYdoc = ( roomId : string ) : { yDoc : Y . Doc ; yMap : Y . Map < string > ; provider : WebsocketProvider } => {
68
+ const initialiseYdoc = ( roomId : string ) : { yDoc : Y . Doc ; yMap : Y . Map < any > ; provider : WebsocketProvider } => {
60
69
const yDoc = new Y . Doc ( ) ;
61
- const yMap : Y . Map < string > = yDoc . getMap ( "sharedMap" ) ;
70
+ const yMap : Y . Map < any > = yDoc . getMap ( "sharedMap" ) ;
62
71
ydocRef . current = yDoc ;
63
72
yMapRef . current = yMap ;
64
73
// TODO: Replace serverUrl once BE ready
65
74
// Test locally across browers with 'HOST=localhost PORT 1234 npx y-websocket'
66
75
const provider = new WebsocketProvider ( "ws://localhost:1234" , roomId , yDoc ) ;
67
76
provider . on ( "status" , ( event : any ) => {
68
77
if ( event . status === "disconnected" ) {
69
- toast . error ( "You have disconnected" ) ;
78
+ // toast.error("You have disconnected");
70
79
}
71
80
} ) ;
72
81
providerRef . current = provider ;
@@ -85,7 +94,7 @@ export const CollaborationProvider: React.FC<{ children: ReactNode }> = ({ child
85
94
} ;
86
95
87
96
// Observer to listen to any changes to shared state (e.g. language changes)
88
- const setUpObserver = ( yMap : Y . Map < string > ) => {
97
+ const setUpObserver = ( yMap : Y . Map < any > ) => {
89
98
yMap . observe ( ( event ) => {
90
99
event . changes . keys . forEach ( ( change , key ) => {
91
100
if ( key === SELECTED_LANGUAGE ) {
@@ -116,12 +125,18 @@ export const CollaborationProvider: React.FC<{ children: ReactNode }> = ({ child
116
125
} ;
117
126
} , [ ] ) ;
118
127
119
- const handleChangeLanguage = ( lang : string ) => {
128
+ const handleChangeLanguage = ( lang : Language ) => {
120
129
yMapRef . current ?. set ( SELECTED_LANGUAGE , lang ) ;
121
130
} ;
122
131
132
+ const handleExecuteCode = ( ) => {
133
+ const sourceCode = editorRef . current ?. getValue ( ) ;
134
+ } ;
135
+
123
136
return (
124
- < CollaborationContext . Provider value = { { initialiseEditor, selectedLanguage, languages, handleChangeLanguage } } >
137
+ < CollaborationContext . Provider
138
+ value = { { initialiseEditor, selectedLanguage, languages, handleChangeLanguage, handleExecuteCode } }
139
+ >
125
140
{ children }
126
141
</ CollaborationContext . Provider >
127
142
) ;
0 commit comments