@@ -6,7 +6,7 @@ import { MonacoBinding } from "y-monaco";
6
6
import { WebsocketProvider } from "y-websocket" ;
7
7
import { useAuth } from "./AuthContext" ;
8
8
import { toast } from "react-toastify" ;
9
- import { AWARENESS_KEYS } from "presentation/utils/constants" ;
9
+ import { COLLABORATION_AWARENESS_KEYS , COLLABORATION_YMAP_KEYS } from "presentation/utils/constants" ;
10
10
11
11
interface CollaborationContextType {
12
12
initialiseEditor : ( roomId : string , editor : any , monaco : Monaco ) => void ;
@@ -18,9 +18,10 @@ const CollaborationContext = createContext<CollaborationContextType | undefined>
18
18
19
19
export const CollaborationProvider : React . FC < { children : ReactNode } > = ( { children } ) => {
20
20
const { user } = useAuth ( ) ;
21
- const userId = user ?. _id ;
21
+ const username = user ?. username ;
22
22
23
- const { USER_ID , SELECTED_LANGUAGE } = AWARENESS_KEYS ;
23
+ const { USERNAME } = COLLABORATION_AWARENESS_KEYS ;
24
+ const { SELECTED_LANGUAGE } = COLLABORATION_YMAP_KEYS ;
24
25
25
26
const [ selectedLanguage , setSelectedLanguage ] = useState < string > ( "javascript" ) ;
26
27
const [ languages , setLanguages ] = useState < { label : string ; value : string } [ ] > ( [ ] ) ;
@@ -40,6 +41,7 @@ export const CollaborationProvider: React.FC<{ children: ReactNode }> = ({ child
40
41
const { yDoc, provider, yMap } = initialiseYdoc ( roomId ) ;
41
42
bindEditorToDoc ( editor , yDoc , provider ) ;
42
43
setUpObserver ( yMap ) ;
44
+ setUpConnectionAwareness ( provider ) ;
43
45
} ;
44
46
45
47
const initialiseLanguages = ( monaco : Monaco ) => {
@@ -63,7 +65,9 @@ export const CollaborationProvider: React.FC<{ children: ReactNode }> = ({ child
63
65
// Test locally across browers with 'HOST=localhost PORT 1234 npx y-websocket'
64
66
const provider = new WebsocketProvider ( "ws://localhost:1234" , roomId , yDoc ) ;
65
67
provider . on ( "status" , ( event : any ) => {
66
- console . log ( event . status ) ;
68
+ if ( event . status === "disconnected" ) {
69
+ toast . error ( "You have disconnected" ) ;
70
+ }
67
71
} ) ;
68
72
providerRef . current = provider ;
69
73
return { yDoc, yMap, provider } ;
@@ -80,6 +84,7 @@ export const CollaborationProvider: React.FC<{ children: ReactNode }> = ({ child
80
84
bindingRef . current = binding ;
81
85
} ;
82
86
87
+ // Observer to listen to any changes to shared state (e.g. language changes)
83
88
const setUpObserver = ( yMap : Y . Map < string > ) => {
84
89
yMap . observe ( ( event ) => {
85
90
event . changes . keys . forEach ( ( change , key ) => {
@@ -93,6 +98,15 @@ export const CollaborationProvider: React.FC<{ children: ReactNode }> = ({ child
93
98
} ) ;
94
99
} ;
95
100
101
+ // Observer to listen to any changes to users' presence (e.g. connection status, is typing, cursor)
102
+ const setUpConnectionAwareness = ( provider : WebsocketProvider ) => {
103
+ provider . awareness . setLocalStateField ( USERNAME , username ) ;
104
+ provider . awareness . on ( "change" , ( update : any ) => {
105
+ const users = provider . awareness . getStates ( ) ;
106
+ // TODO: Some UI feedback about connection status of the other user
107
+ } ) ;
108
+ } ;
109
+
96
110
useEffect ( ( ) => {
97
111
return ( ) => {
98
112
bindingRef . current ?. destroy ( ) ;
0 commit comments