|
1 | 1 | import { INTEGRATION_SERVICE, IntegrationService } from 'src/app/integration'; |
2 | 2 | import { ConnectedPosition } from '@angular/cdk/overlay'; |
3 | 3 | import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Inject, OnInit, Output, inject } from '@angular/core'; |
4 | | -import { ConfigService, DebugAPI, PortapiService, SPNService, StringSetting } from '@safing/portmaster-api'; |
| 4 | +import { ConfigService, DebugAPI, PortapiService, SPNService, StringSetting, BoolSetting } from '@safing/portmaster-api'; |
5 | 5 | import { tap } from 'rxjs/operators'; |
6 | 6 | import { AppComponent } from 'src/app/app.component'; |
7 | | -import { NotificationType, NotificationsService, StatusService, VersionStatus } from 'src/app/services'; |
| 7 | +import { NotificationType, NotificationsService, StatusService, VersionStatus, GetModuleState, ControlPauseStateData } from 'src/app/services'; |
8 | 8 | import { ActionIndicatorService } from 'src/app/shared/action-indicator'; |
9 | 9 | import { fadeInAnimation, fadeOutAnimation } from 'src/app/shared/animations'; |
10 | 10 | import { ExitService } from 'src/app/shared/exit-screen'; |
@@ -36,12 +36,34 @@ export class NavigationComponent implements OnInit { |
36 | 36 | /** The color to use for the notifcation-available hint (dot) */ |
37 | 37 | notificationColor: string = 'text-green-300'; |
38 | 38 |
|
| 39 | + pauseState: ControlPauseStateData | null = null; |
| 40 | + get isPaused(): boolean { return this.pauseState?.Interception===true || this.pauseState?.SPN===true; } |
| 41 | + get isPausedInterception(): boolean { return this.pauseState?.Interception===true; } |
| 42 | + get isPausedSPN(): boolean { return this.pauseState?.SPN===true; } |
| 43 | + get pauseInfo(): string { |
| 44 | + if (this.pauseState?.Interception===true && this.pauseState?.SPN===true) |
| 45 | + return 'Portmaster and SPN are paused'; |
| 46 | + else if (this.pauseState?.Interception===true) |
| 47 | + return 'Portmaster is paused'; |
| 48 | + else if (this.pauseState?.SPN===true) |
| 49 | + return 'SPN is paused'; |
| 50 | + return ''; |
| 51 | + } |
| 52 | + get pauseInfoTillTime(): string { |
| 53 | + if (this.isPaused && this.pauseState?.TillTime) |
| 54 | + return new Date(this.pauseState.TillTime).toLocaleTimeString(undefined, { hour12: false }); |
| 55 | + return ''; |
| 56 | + } |
| 57 | + |
39 | 58 | /** Whether or not we have new, unseen prompts */ |
40 | 59 | hasNewPrompts = false; |
41 | 60 |
|
42 | 61 | /** Whether or not prompting is globally enabled. */ |
43 | 62 | globalPromptingEnabled = false; |
44 | 63 |
|
| 64 | + /** Whether or not the SPN is currently enabled */ |
| 65 | + spnEnabled = false; |
| 66 | + |
45 | 67 | @Output() |
46 | 68 | sideDashChange = new EventEmitter<'collapsed' | 'expanded' | 'force-overlay'>(); |
47 | 69 |
|
@@ -93,11 +115,21 @@ export class NavigationComponent implements OnInit { |
93 | 115 | this.cdr.markForCheck(); |
94 | 116 | }); |
95 | 117 |
|
| 118 | + this.statusService.status$.subscribe(status => { |
| 119 | + this.pauseState = GetModuleState(status, 'Control', 'control:paused')?.Data || null; |
| 120 | + }); |
| 121 | + |
96 | 122 | this.configService.watch<StringSetting>('filter/defaultAction') |
97 | 123 | .subscribe(defaultAction => { |
98 | 124 | this.globalPromptingEnabled = defaultAction === 'ask'; |
99 | 125 | this.cdr.markForCheck(); |
100 | 126 | }) |
| 127 | + |
| 128 | + this.configService.watch<BoolSetting>("spn/enable") |
| 129 | + .subscribe(value => { |
| 130 | + this.spnEnabled = value; |
| 131 | + this.cdr.markForCheck(); |
| 132 | + }); |
101 | 133 |
|
102 | 134 | this.notificationService.new$ |
103 | 135 | .subscribe(notif => { |
@@ -251,6 +283,43 @@ export class NavigationComponent implements OnInit { |
251 | 283 | )) |
252 | 284 | } |
253 | 285 |
|
| 286 | + pause(event: Event, duration: number) { |
| 287 | + // prevent default and stop-propagation to avoid |
| 288 | + // expanding the accordion body. |
| 289 | + event.preventDefault(); |
| 290 | + event.stopPropagation(); |
| 291 | + |
| 292 | + this.portapi.pause(duration, false) |
| 293 | + .subscribe(this.actionIndicator.httpObserver( |
| 294 | + 'Pausing ...', |
| 295 | + 'Failed to Pause', |
| 296 | + )) |
| 297 | + } |
| 298 | + pauseSPN(event: Event, duration: number) { |
| 299 | + // prevent default and stop-propagation to avoid |
| 300 | + // expanding the accordion body. |
| 301 | + event.preventDefault(); |
| 302 | + event.stopPropagation(); |
| 303 | + |
| 304 | + this.portapi.pause(duration, true) |
| 305 | + .subscribe(this.actionIndicator.httpObserver( |
| 306 | + 'Pausing SPN...', |
| 307 | + 'Failed to Pause SPN', |
| 308 | + )) |
| 309 | + } |
| 310 | + resume(event: Event) { |
| 311 | + // prevent default and stop-propagation to avoid |
| 312 | + // expanding the accordion body. |
| 313 | + event.preventDefault(); |
| 314 | + event.stopPropagation(); |
| 315 | + |
| 316 | + this.portapi.resume() |
| 317 | + .subscribe(this.actionIndicator.httpObserver( |
| 318 | + 'Resuming ...', |
| 319 | + 'Failed to Resume', |
| 320 | + )) |
| 321 | + } |
| 322 | + |
254 | 323 | /** |
255 | 324 | * @private |
256 | 325 | * Opens the data-directory of the portmaster installation. |
|
0 commit comments