@@ -26,6 +26,38 @@ const WEBSOCKET_SERVER = SHOULD_USE_DEV_YJS_SERVER
2626 ? 'ws://localhost:1234'
2727 : 'wss://yjs.usaco.guide:443' ;
2828
29+ const createWebsocketInterceptorClass = (
30+ onMessageSyncHandler : ( ) => void ,
31+ onSaveHandler : ( ) => void
32+ ) => {
33+ return class WebsocketInterceptor extends WebSocket {
34+ send ( data : string | ArrayBuffer | Blob | ArrayBufferView ) {
35+ const messageSync = 0 ; // defined in y-websocket
36+ if (
37+ data instanceof Uint8Array &&
38+ data . length > 0 &&
39+ data [ 0 ] === messageSync
40+ ) {
41+ console . log ( data ) ;
42+ onMessageSyncHandler ( ) ;
43+ }
44+ super . send ( data ) ;
45+ }
46+
47+ set onmessage ( f : any ) {
48+ const messageSaved = 100 ; // defined in ide-yjs
49+ super . onmessage = m => {
50+ const decoder = new Uint8Array ( m . data ) ;
51+ if ( decoder . length > 0 && decoder [ 0 ] === messageSaved ) {
52+ onSaveHandler ( ) ;
53+ } else {
54+ f ( m ) ;
55+ }
56+ } ;
57+ }
58+ } ;
59+ } ;
60+
2961const RealtimeEditor = ( {
3062 defaultValue,
3163 yjsDocumentId,
@@ -43,7 +75,7 @@ const RealtimeEditor = ({
4375 } | null > ( null ) ;
4476
4577 const [ connectionStatus , setConnectionStatus ] = useState <
46- 'disconnected' | 'connecting' | 'connected '
78+ 'disconnected' | 'connecting' | 'saved' | 'saving '
4779 > ( 'disconnected' ) ;
4880 const [ isSynced , setIsSynced ] = useState < boolean > ( false ) ;
4981
@@ -58,10 +90,31 @@ const RealtimeEditor = ({
5890 const documentId = yjsDocumentId ;
5991
6092 const ydocument = new Y . Doc ( ) ;
93+
94+ let lastUpdate = 0 ;
95+ const CustomWebsocketInterceptor = createWebsocketInterceptorClass (
96+ ( ) => {
97+ if ( ! provider . _synced ) {
98+ return ;
99+ }
100+
101+ // As a sketchy hack, we'll assume every sync message sent
102+ // corresponds to an edit the user made.
103+ lastUpdate = Date . now ( ) ;
104+ setConnectionStatus ( 'saving' ) ;
105+ } ,
106+ ( ) => {
107+ if ( Date . now ( ) - lastUpdate > 1000 ) {
108+ setConnectionStatus ( 'saved' ) ;
109+ }
110+ }
111+ ) ;
112+
61113 const provider = new WebsocketProvider (
62114 WEBSOCKET_SERVER ,
63115 documentId ,
64- ydocument
116+ ydocument ,
117+ { WebSocketPolyfill : CustomWebsocketInterceptor }
65118 ) ;
66119
67120 // Set the cursor color
@@ -118,7 +171,7 @@ const RealtimeEditor = ({
118171 provider . on (
119172 'status' ,
120173 ( { status } : { status : 'disconnected' | 'connecting' | 'connected' } ) => {
121- setConnectionStatus ( status ) ;
174+ setConnectionStatus ( status === 'connected' ? 'saved' : status ) ;
122175 }
123176 ) ;
124177 provider . on ( 'sync' , ( isSynced : boolean ) => {
0 commit comments