1
- import { Component , HostBinding } from "@angular/core" ;
1
+ import { Component , HostBinding , ViewChild , ElementRef } from "@angular/core" ;
2
2
import { UpgradableComponent } from "theme/components/upgradable" ;
3
3
import {
4
4
ResultMessage ,
@@ -22,7 +22,10 @@ import {
22
22
PluginLogMessageDTO
23
23
} from "chatoverflow-api" ;
24
24
import { CryptoService } from "../../../crypto.service" ;
25
- import { interval } from "rxjs" ;
25
+
26
+ interface PluginInstanceWithLog extends PluginInstance {
27
+ log ?: string [ ] ;
28
+ }
26
29
27
30
@Component ( {
28
31
selector : 'better-repl' ,
@@ -31,6 +34,7 @@ import {interval} from "rxjs";
31
34
} )
32
35
export class BetterREPLComponent extends UpgradableComponent {
33
36
@HostBinding ( 'class.mdl-grid' ) private readonly mdlGrid = true ;
37
+ @ViewChild ( 'instanceLog' ) private readonly instanceLog : ElementRef < HTMLDivElement > ;
34
38
35
39
private lastRequestCommand = "..." ;
36
40
private lastRequestMessage = "Please send a request to the server..." ;
@@ -44,7 +48,7 @@ export class BetterREPLComponent extends UpgradableComponent {
44
48
private pluginTypes : Array < PluginType > ;
45
49
46
50
private connectorKeys : Array < ConnectorKey > ;
47
- private pluginInstances : Array < PluginInstance > ;
51
+ private pluginInstances : Array < PluginInstanceWithLog > ;
48
52
49
53
private instanceLogOutput : Array < string > ;
50
54
private instanceRequirements : Array < Requirement > ;
@@ -65,9 +69,8 @@ export class BetterREPLComponent extends UpgradableComponent {
65
69
private changeReqTypeValue = "" ;
66
70
private changeReqValueValue = "" ;
67
71
68
- private pingpongCounter = interval ( 5000 ) ;
69
- private pingpongStarted = false ;
70
- private pingPongSubscriber = null ;
72
+ private eventsStarted = false ;
73
+ private eventSource : EventSource = null ;
71
74
72
75
constructor ( private configService : ConfigService , private typeService : TypeService ,
73
76
private connectorService : ConnectorService , private instanceService : InstanceService ,
@@ -155,45 +158,74 @@ export class BetterREPLComponent extends UpgradableComponent {
155
158
this . lastPassword = password ;
156
159
}
157
160
this . reloadEverything ( ! response . success ) ;
158
- this . handlePingpong ( true ) ;
161
+ this . handleEvents ( true ) ;
159
162
} , error => {
160
163
this . logGenericError ( "postLogin" ) ;
161
164
this . reloadEverything ( true ) ;
162
165
} ) ;
163
166
}
164
167
165
- handlePingpong ( start : boolean ) {
168
+ handleEvents ( start : boolean ) {
169
+ if ( ! ( "EventSource" in window ) ) {
170
+ console . warn ( "Event source is not supported" ) ;
171
+ return ;
172
+ }
173
+
166
174
if ( start ) {
167
- if ( ! this . pingpongStarted ) {
168
- this . pingPongSubscriber = this . pingpongCounter . subscribe ( n => this . pingpong ( ) ) ;
169
- this . pingpongStarted = true ;
175
+ if ( ! this . eventsStarted ) {
176
+ //todo find a better way to get the basePath
177
+ this . eventSource = new EventSource ( `${ this . configService [ "basePath" ] } /events?authKey=${ this . authKey } ` ) ;
178
+ this . eventSource . onerror = ( ) => {
179
+ console . log ( "Lost connection. Trying to reconnect..." ) ;
180
+ setTimeout ( ( ) => this . login ( this . lastPassword ) , 1000 ) ;
181
+ } ;
182
+ this . eventSource . addEventListener ( "instance" , ( e : MessageEvent ) => {
183
+ const { name, action, data } = JSON . parse ( e . data ) as { name : string , action : string , data ?: { message : string , timestamp : string } } ;
184
+ const instance = this . pluginInstances . find ( i => i . instanceName === name ) ;
185
+ if ( ! instance )
186
+ return ;
187
+
188
+ switch ( action ) {
189
+ case "start" :
190
+ instance . isRunning = true ;
191
+ break ;
192
+ case "stop" :
193
+ instance . isRunning = false ;
194
+ break ;
195
+ case "log" :
196
+ if ( data ) {
197
+ if ( ! instance . log )
198
+ instance . log = [ ] ;
199
+
200
+ instance . log . push ( `${ new Date ( data . timestamp ) . toLocaleTimeString ( ) } - ${ data . message } ` ) ;
201
+ if ( name === this . instanceNameSSValue ) {
202
+ this . instanceLogOutput = instance . log ;
203
+ if ( this . instanceLog && this . instanceLog . nativeElement ) {
204
+ const element = this . instanceLog . nativeElement ;
205
+ if ( element . scrollTop + element . clientHeight === element . scrollHeight )
206
+ setTimeout ( ( ) => element . scrollTop = element . scrollHeight , 0 ) ;
207
+ }
208
+ } else if ( this . instanceLogOutput === instance . log ) {
209
+ this . instanceLogOutput = [ ] ;
210
+ }
211
+ }
212
+ break ;
213
+ }
214
+ } ) ;
215
+ this . eventSource . addEventListener ( "close" , ( ) => {
216
+ this . eventSource . close ( ) ;
217
+ this . eventSource = null ;
218
+ } ) ;
219
+ this . eventsStarted = true ;
170
220
}
171
221
} else {
172
- if ( this . pingPongSubscriber != null ) {
173
- this . pingPongSubscriber . unsubscribe ( ) ;
222
+ if ( this . eventSource ) {
223
+ this . eventSource . close ( ) ;
174
224
}
175
- this . pingpongStarted = false ;
225
+ this . eventsStarted = false ;
176
226
}
177
227
}
178
228
179
- pingpong ( ) {
180
- this . configService . postPing ( this . authKey ) . subscribe ( ( response : ResultMessage ) => {
181
- if ( response . success ) {
182
- // Pong
183
- } else {
184
- this . reloadEverything ( true ) ;
185
- }
186
- } , error => {
187
- if ( error . status == 401 || error . status == 400 ) {
188
- // Try to login again
189
- this . login ( this . lastPassword ) ;
190
-
191
- } else if ( error . status == 0 ) {
192
- this . reloadEverything ( true ) ;
193
- }
194
- } )
195
- }
196
-
197
229
register ( password : string ) {
198
230
this . configService . postRegister ( { password : password } ) . subscribe ( ( response : ResultMessage ) => {
199
231
this . logResultMessage ( "postRegister" , response ) ;
@@ -202,7 +234,7 @@ export class BetterREPLComponent extends UpgradableComponent {
202
234
this . reloadEverything ( false ) ;
203
235
}
204
236
this . reloadEverything ( ! response . success ) ;
205
- this . handlePingpong ( true ) ;
237
+ this . handleEvents ( true ) ;
206
238
} , error => {
207
239
this . logGenericError ( "postRegister" ) ;
208
240
this . reloadEverything ( true ) ;
0 commit comments