@acorex-platform/framework-client 0.0.15 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/acorex-platform-framework-client-auth.mjs +872 -314
- package/fesm2022/acorex-platform-framework-client-auth.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-common-common-settings.provider-Euotv9l0.mjs → acorex-platform-framework-client-common-common-settings.provider-CLm2BVk-.mjs} +88 -5
- package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-CLm2BVk-.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-common.mjs +2685 -898
- package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-core.mjs +691 -823
- package/fesm2022/acorex-platform-framework-client-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-domain.mjs +16 -16
- package/fesm2022/acorex-platform-framework-client-layout-builder.mjs +181 -84
- package/fesm2022/acorex-platform-framework-client-layout-builder.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-CjnQ9hAJ.mjs → acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-oE8CeLE8.mjs} +8 -6
- package/fesm2022/{acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-CjnQ9hAJ.mjs.map → acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-oE8CeLE8.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-fFen8w8M.mjs → acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-BtLEUWAA.mjs} +4 -4
- package/fesm2022/{acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-fFen8w8M.mjs.map → acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-BtLEUWAA.mjs.map} +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-components.mjs +3300 -1236
- package/fesm2022/acorex-platform-framework-client-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-designer.mjs +277 -185
- package/fesm2022/acorex-platform-framework-client-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BXOMs6oD.mjs +29184 -0
- package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BXOMs6oD.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-BzUM-JMC.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-DCK-qb-F.mjs} +34 -20
- package/fesm2022/acorex-platform-framework-client-layout-entity-attachments-page.component-DCK-qb-F.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-entity-bulk-entity.command-Cs3agnpF.mjs +162 -0
- package/fesm2022/acorex-platform-framework-client-layout-entity-bulk-entity.command-Cs3agnpF.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-Ci_CTFtq.mjs → acorex-platform-framework-client-layout-entity-file-list-popup.component-p0hxDb0W.mjs} +31 -19
- package/fesm2022/acorex-platform-framework-client-layout-entity-file-list-popup.component-p0hxDb0W.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-DmiB__JR.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-DYV9YPyw.mjs} +30 -18
- package/fesm2022/acorex-platform-framework-client-layout-entity-gallery-page.component-DYV9YPyw.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +2 -26780
- package/fesm2022/acorex-platform-framework-client-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-views.mjs +421 -151
- package/fesm2022/acorex-platform-framework-client-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs +673 -287
- package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-button-widget-designer.component-CIwpAXbL.mjs → acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BiWerYcu.mjs} +16 -10
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-button-widget-designer.component-CIwpAXbL.mjs.map → acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BiWerYcu.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-image-preview.popup-CazpERbX.mjs → acorex-platform-framework-client-layout-widgets-image-preview.popup-BOrrMm3U.mjs} +9 -8
- package/fesm2022/acorex-platform-framework-client-layout-widgets-image-preview.popup-BOrrMm3U.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-page-widget-designer.component-DKkJi40s.mjs → acorex-platform-framework-client-layout-widgets-page-widget-designer.component-WzIiwnGC.mjs} +20 -12
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-page-widget-designer.component-DKkJi40s.mjs.map → acorex-platform-framework-client-layout-widgets-page-widget-designer.component-WzIiwnGC.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-DtYZfA79.mjs → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-3CO4xJB3.mjs} +32 -18
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-DtYZfA79.mjs.map → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-3CO4xJB3.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-nMUtxAyy.mjs → acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-CRST84ou.mjs} +8 -7
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-nMUtxAyy.mjs.map → acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-CRST84ou.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-view-popup.component-DvUSZ4hJ.mjs → acorex-platform-framework-client-layout-widgets-tabular-data-view-popup.component-FjtSRxIX.mjs} +4 -4
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-view-popup.component-DvUSZ4hJ.mjs.map → acorex-platform-framework-client-layout-widgets-tabular-data-view-popup.component-FjtSRxIX.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-BihIfkZW.mjs → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-D6HFPmGC.mjs} +10 -8
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-BihIfkZW.mjs.map → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-D6HFPmGC.mjs.map} +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs +4907 -2554
- package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-native.mjs +7 -7
- package/fesm2022/acorex-platform-framework-client-realtime-set-presence-availability.command-CetlUjnM.mjs +29 -0
- package/fesm2022/acorex-platform-framework-client-realtime-set-presence-availability.command-CetlUjnM.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-realtime.mjs +463 -26
- package/fesm2022/acorex-platform-framework-client-realtime.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-runtime.mjs +300 -137
- package/fesm2022/acorex-platform-framework-client-runtime.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-create-view.component-QIFX11dh.mjs → acorex-platform-framework-client-themes-default-entity-master-create-view.component-yeftgJ_K.mjs} +10 -7
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-create-view.component-QIFX11dh.mjs.map → acorex-platform-framework-client-themes-default-entity-master-create-view.component-yeftgJ_K.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-modify-view.component-BBdellyL.mjs → acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DWE3OWGm.mjs} +10 -7
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-modify-view.component-BBdellyL.mjs.map → acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DWE3OWGm.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-single-view.component-CIf1VWNW.mjs → acorex-platform-framework-client-themes-default-entity-master-single-view.component-C2Abf7Lb.mjs} +21 -19
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-C2Abf7Lb.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-401.component-C_czT_JC.mjs → acorex-platform-framework-client-themes-default-error-401.component-BrTotLx1.mjs} +5 -5
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-401.component-C_czT_JC.mjs.map → acorex-platform-framework-client-themes-default-error-401.component-BrTotLx1.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-404.component-C2Wu0YtF.mjs → acorex-platform-framework-client-themes-default-error-404.component-DsC7_s59.mjs} +5 -5
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-404.component-C2Wu0YtF.mjs.map → acorex-platform-framework-client-themes-default-error-404.component-DsC7_s59.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-offline.component-DRz-kVsT.mjs → acorex-platform-framework-client-themes-default-error-offline.component-CngiQycG.mjs} +6 -6
- package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-CngiQycG.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-themes-default.mjs +448 -277
- package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-shared-icon-chooser-column.component-Ci_oH7NE.mjs → acorex-platform-framework-client-themes-shared-icon-chooser-column.component-CbZALjB5.mjs} +8 -6
- package/fesm2022/{acorex-platform-framework-client-themes-shared-icon-chooser-column.component-Ci_oH7NE.mjs.map → acorex-platform-framework-client-themes-shared-icon-chooser-column.component-CbZALjB5.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-shared-icon-chooser-view.component-Lb1G2Xz7.mjs → acorex-platform-framework-client-themes-shared-icon-chooser-view.component-BRrNT6x2.mjs} +8 -6
- package/fesm2022/{acorex-platform-framework-client-themes-shared-icon-chooser-view.component-Lb1G2Xz7.mjs.map → acorex-platform-framework-client-themes-shared-icon-chooser-view.component-BRrNT6x2.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-shared-theme-color-chooser-column.component-D4ubvFYf.mjs → acorex-platform-framework-client-themes-shared-theme-color-chooser-column.component-BIsQTr6B.mjs} +4 -4
- package/fesm2022/{acorex-platform-framework-client-themes-shared-theme-color-chooser-column.component-D4ubvFYf.mjs.map → acorex-platform-framework-client-themes-shared-theme-color-chooser-column.component-BIsQTr6B.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-shared-theme-color-chooser-view.component-Br8j_BF_.mjs → acorex-platform-framework-client-themes-shared-theme-color-chooser-view.component-ZclmSbt9.mjs} +16 -10
- package/fesm2022/{acorex-platform-framework-client-themes-shared-theme-color-chooser-view.component-Br8j_BF_.mjs.map → acorex-platform-framework-client-themes-shared-theme-color-chooser-view.component-ZclmSbt9.mjs.map} +1 -1
- package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +538 -133
- package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-workflow.mjs +26 -66
- package/fesm2022/acorex-platform-framework-client-workflow.mjs.map +1 -1
- package/package.json +10 -10
- package/realtime/README.md +16 -0
- package/runtime/README.md +14 -0
- package/types/acorex-platform-framework-client-auth.d.ts +291 -52
- package/types/acorex-platform-framework-client-common.d.ts +615 -202
- package/types/acorex-platform-framework-client-core.d.ts +215 -225
- package/types/acorex-platform-framework-client-layout-builder.d.ts +24 -8
- package/types/acorex-platform-framework-client-layout-components.d.ts +407 -94
- package/types/acorex-platform-framework-client-layout-entity.d.ts +734 -411
- package/types/acorex-platform-framework-client-layout-views.d.ts +40 -15
- package/types/acorex-platform-framework-client-layout-widget-core.d.ts +66 -17
- package/types/acorex-platform-framework-client-layout-widgets.d.ts +295 -68
- package/types/acorex-platform-framework-client-realtime.d.ts +183 -6
- package/types/acorex-platform-framework-client-runtime.d.ts +134 -28
- package/types/acorex-platform-framework-client-themes-default.d.ts +9 -1
- package/types/acorex-platform-framework-client-themes-shared.d.ts +8 -2
- package/types/acorex-platform-framework-client-workflow.d.ts +12 -37
- package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-Euotv9l0.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity-attachments-page.component-BzUM-JMC.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity-file-list-popup.component-Ci_CTFtq.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity-gallery-page.component-DmiB__JR.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets-image-preview.popup-CazpERbX.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-CIf1VWNW.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-DRz-kVsT.mjs.map +0 -1
|
@@ -2,11 +2,11 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { NgModule, Injectable } from '@angular/core';
|
|
3
3
|
|
|
4
4
|
class AXPNativeModule {
|
|
5
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
6
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
7
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
5
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPNativeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
6
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXPNativeModule }); }
|
|
7
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPNativeModule }); }
|
|
8
8
|
}
|
|
9
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
9
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPNativeModule, decorators: [{
|
|
10
10
|
type: NgModule,
|
|
11
11
|
args: [{
|
|
12
12
|
imports: [],
|
|
@@ -139,10 +139,10 @@ class AXPNativeService {
|
|
|
139
139
|
console.error('FlutterChannel is not defined');
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
143
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
142
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPNativeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
143
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPNativeService, providedIn: 'root' }); }
|
|
144
144
|
}
|
|
145
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
145
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPNativeService, decorators: [{
|
|
146
146
|
type: Injectable,
|
|
147
147
|
args: [{ providedIn: 'root' }]
|
|
148
148
|
}], ctorParameters: () => [] });
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { runtimeCommandFailure, runtimeCommandSuccessObject } from '@acorex-platform/framework-shared/core';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { inject, Injectable } from '@angular/core';
|
|
4
|
+
import { AXPUserPresenceService } from './acorex-platform-framework-client-realtime.mjs';
|
|
5
|
+
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region ----- Command -----
|
|
8
|
+
class AXPSetPresenceAvailabilityCommand {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.presence = inject(AXPUserPresenceService);
|
|
11
|
+
}
|
|
12
|
+
async execute(input) {
|
|
13
|
+
const status = input?.status;
|
|
14
|
+
if (status !== 'online' && status !== 'away' && status !== 'busy') {
|
|
15
|
+
return runtimeCommandFailure('Invalid presence status');
|
|
16
|
+
}
|
|
17
|
+
await this.presence.setAvailability(status, 'manual');
|
|
18
|
+
return runtimeCommandSuccessObject(undefined);
|
|
19
|
+
}
|
|
20
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPSetPresenceAvailabilityCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
21
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPSetPresenceAvailabilityCommand, providedIn: 'root' }); }
|
|
22
|
+
}
|
|
23
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPSetPresenceAvailabilityCommand, decorators: [{
|
|
24
|
+
type: Injectable,
|
|
25
|
+
args: [{ providedIn: 'root' }]
|
|
26
|
+
}] });
|
|
27
|
+
|
|
28
|
+
export { AXPSetPresenceAvailabilityCommand };
|
|
29
|
+
//# sourceMappingURL=acorex-platform-framework-client-realtime-set-presence-availability.command-CetlUjnM.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acorex-platform-framework-client-realtime-set-presence-availability.command-CetlUjnM.mjs","sources":["../../../../../libs/framework/client/realtime/src/lib/presence/set-presence-availability.command.ts"],"sourcesContent":["import { AXPCommand, type AXPCommandExecuteResultPromise } from '@acorex-platform/framework-shared/runtime';\nimport { runtimeCommandFailure, runtimeCommandSuccessObject } from '@acorex-platform/framework-shared/core';\nimport { inject, Injectable } from '@angular/core';\nimport { AXPUserPresenceService } from './user-presence.service';\n\n//#region ----- Types -----\n\nexport interface AXPSetPresenceAvailabilityInput {\n status?: 'online' | 'away' | 'busy';\n}\n\n//#endregion\n\n//#region ----- Command -----\n\n@Injectable({ providedIn: 'root' })\nexport class AXPSetPresenceAvailabilityCommand implements AXPCommand<AXPSetPresenceAvailabilityInput, void> {\n private readonly presence = inject(AXPUserPresenceService);\n\n async execute(input?: AXPSetPresenceAvailabilityInput): AXPCommandExecuteResultPromise<void> {\n const status = input?.status;\n if (status !== 'online' && status !== 'away' && status !== 'busy') {\n return runtimeCommandFailure('Invalid presence status');\n }\n await this.presence.setAvailability(status, 'manual');\n return runtimeCommandSuccessObject(undefined);\n }\n}\n\n//#endregion\n"],"names":[],"mappings":";;;;;AAWA;AAEA;MAGa,iCAAiC,CAAA;AAD9C,IAAA,WAAA,GAAA;AAEmB,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,sBAAsB,CAAC;AAU3D,IAAA;IARC,MAAM,OAAO,CAAC,KAAuC,EAAA;AACnD,QAAA,MAAM,MAAM,GAAG,KAAK,EAAE,MAAM;AAC5B,QAAA,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,MAAM,EAAE;AACjE,YAAA,OAAO,qBAAqB,CAAC,yBAAyB,CAAC;QACzD;QACA,MAAM,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC;AACrD,QAAA,OAAO,2BAA2B,CAAC,SAAS,CAAC;IAC/C;8GAVW,iCAAiC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAjC,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iCAAiC,cADpB,MAAM,EAAA,CAAA,CAAA;;2FACnB,iCAAiC,EAAA,UAAA,EAAA,CAAA;kBAD7C,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;;;"}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, Optional, Inject, Injectable, inject,
|
|
2
|
+
import { InjectionToken, Optional, Inject, Injectable, inject, DestroyRef, makeEnvironmentProviders } from '@angular/core';
|
|
3
3
|
import { AXPSessionService, AXPSessionStatus } from '@acorex-platform/framework-client/auth';
|
|
4
4
|
import { io } from 'socket.io-client';
|
|
5
|
-
import { BehaviorSubject } from 'rxjs';
|
|
5
|
+
import { BehaviorSubject, Subject } from 'rxjs';
|
|
6
|
+
import { provideAppStartUpTask, AXP_APP_STARTUP_PRIORITY } from '@acorex-platform/framework-client/core';
|
|
7
|
+
import { provideCommandSetups } from '@acorex-platform/framework-client/runtime';
|
|
8
|
+
import { PRESENCE_SET_AVAILABILITY } from '@acorex-platform/framework-shared/runtime';
|
|
9
|
+
import { DOCUMENT } from '@angular/common';
|
|
10
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
6
11
|
|
|
7
12
|
//#region ---- Client realtime types ----
|
|
8
13
|
//#endregion
|
|
@@ -10,10 +15,18 @@ import { BehaviorSubject } from 'rxjs';
|
|
|
10
15
|
//#region ---- Client topic constants (mirror server) ----
|
|
11
16
|
const AXP_REALTIME_TOPIC_INBOX_REFRESH = 'inbox.refresh';
|
|
12
17
|
const AXP_REALTIME_TOPIC_CONVERSATION_MESSAGE = 'conversation.message';
|
|
18
|
+
const AXP_REALTIME_TOPIC_CONVERSATION_TYPING = 'conversation.typing';
|
|
19
|
+
const AXP_REALTIME_TOPIC_CONVERSATION_CALL = 'conversation.call';
|
|
13
20
|
const AXP_REALTIME_TOPIC_ENTITY_MUTATION = 'entity.mutation';
|
|
21
|
+
const AXP_REALTIME_TOPIC_USER_PRESENCE = 'user.presence';
|
|
14
22
|
const AXP_REALTIME_SOCKET_EVENT = 'realtime';
|
|
15
23
|
const AXP_REALTIME_SUBSCRIBE_CONVERSATION = 'subscribe.conversation';
|
|
16
24
|
const AXP_REALTIME_UNSUBSCRIBE_CONVERSATION = 'unsubscribe.conversation';
|
|
25
|
+
const AXP_REALTIME_SUBSCRIBE_PRESENCE = 'subscribe.presence';
|
|
26
|
+
const AXP_REALTIME_UNSUBSCRIBE_PRESENCE = 'unsubscribe.presence';
|
|
27
|
+
const AXP_REALTIME_PRESENCE_LEAVE = 'presence.leave';
|
|
28
|
+
const AXP_REALTIME_PRESENCE_SET = 'presence.set';
|
|
29
|
+
const AXP_REALTIME_EMIT_TYPING = 'conversation.typing.emit';
|
|
17
30
|
//#endregion
|
|
18
31
|
|
|
19
32
|
//#region ---- Realtime URL helpers ----
|
|
@@ -67,10 +80,10 @@ class AXPRealtimeDispatcherService {
|
|
|
67
80
|
await registration.handle(envelope);
|
|
68
81
|
}
|
|
69
82
|
}
|
|
70
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
71
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
83
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPRealtimeDispatcherService, deps: [{ token: AXP_REALTIME_TOPIC_HANDLER, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
84
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPRealtimeDispatcherService }); }
|
|
72
85
|
}
|
|
73
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
86
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPRealtimeDispatcherService, decorators: [{
|
|
74
87
|
type: Injectable
|
|
75
88
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
76
89
|
type: Optional
|
|
@@ -79,9 +92,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
79
92
|
args: [AXP_REALTIME_TOPIC_HANDLER]
|
|
80
93
|
}] }] });
|
|
81
94
|
|
|
82
|
-
|
|
83
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Always-on realtime connection used by the app shell.
|
|
97
|
+
* Built-in implementation uses Socket.IO; alternate backends may replace this port.
|
|
98
|
+
*/
|
|
99
|
+
class AXPRealtimeConnectionPort {
|
|
100
|
+
}
|
|
101
|
+
//#endregion
|
|
102
|
+
|
|
103
|
+
//#region ---- Socket.IO connection (built-in) ----
|
|
104
|
+
/**
|
|
105
|
+
* Built-in always-on realtime connection via Socket.IO.
|
|
106
|
+
*/
|
|
107
|
+
class AXPRealtimeConnectionService extends AXPRealtimeConnectionPort {
|
|
84
108
|
constructor(config) {
|
|
109
|
+
super();
|
|
85
110
|
this.config = config;
|
|
86
111
|
this.session = inject(AXPSessionService);
|
|
87
112
|
this.dispatcher = inject(AXPRealtimeDispatcherService);
|
|
@@ -95,11 +120,11 @@ class AXPRealtimeConnectionService {
|
|
|
95
120
|
return;
|
|
96
121
|
}
|
|
97
122
|
this.statusSub = this.session.status$.subscribe((status) => {
|
|
98
|
-
if (status === AXPSessionStatus.
|
|
123
|
+
if (status === AXPSessionStatus.Authorized) {
|
|
99
124
|
this.connect();
|
|
100
125
|
}
|
|
101
126
|
else {
|
|
102
|
-
this.
|
|
127
|
+
void this.leaveAndDisconnect();
|
|
103
128
|
}
|
|
104
129
|
});
|
|
105
130
|
}
|
|
@@ -107,10 +132,14 @@ class AXPRealtimeConnectionService {
|
|
|
107
132
|
this.statusSub?.unsubscribe();
|
|
108
133
|
this.disconnect();
|
|
109
134
|
}
|
|
135
|
+
/** Sign-out: tell the server to skip grace, then close the socket. */
|
|
136
|
+
async leaveAndDisconnect() {
|
|
137
|
+
await this.leavePresence();
|
|
138
|
+
this.disconnect();
|
|
139
|
+
}
|
|
110
140
|
connect() {
|
|
111
|
-
const token = this.session.getToken()?.trim();
|
|
112
141
|
const url = this.config?.url?.trim();
|
|
113
|
-
if (!
|
|
142
|
+
if (!url || !this.session.hasSessionCredentials()) {
|
|
114
143
|
this.connectionStatusSubject.next('disconnected');
|
|
115
144
|
return;
|
|
116
145
|
}
|
|
@@ -122,9 +151,10 @@ class AXPRealtimeConnectionService {
|
|
|
122
151
|
return;
|
|
123
152
|
}
|
|
124
153
|
this.connectionStatusSubject.next('connecting');
|
|
154
|
+
// Auth uses HttpOnly access cookie (same-site / proxied); no token in JS.
|
|
125
155
|
this.socket = io(url, {
|
|
126
156
|
transports: ['websocket', 'polling'],
|
|
127
|
-
|
|
157
|
+
withCredentials: true,
|
|
128
158
|
autoConnect: true,
|
|
129
159
|
reconnection: true,
|
|
130
160
|
});
|
|
@@ -177,10 +207,57 @@ class AXPRealtimeConnectionService {
|
|
|
177
207
|
this.joinedConversations.delete(id);
|
|
178
208
|
this.socket?.emit(AXP_REALTIME_UNSUBSCRIBE_CONVERSATION, { conversationId: id });
|
|
179
209
|
}
|
|
180
|
-
|
|
181
|
-
|
|
210
|
+
emitConversationTyping(conversationId, active) {
|
|
211
|
+
const id = conversationId?.trim();
|
|
212
|
+
if (!id || !this.socket?.connected) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
this.socket.emit(AXP_REALTIME_EMIT_TYPING, { conversationId: id, active });
|
|
216
|
+
}
|
|
217
|
+
subscribePresence(userIds) {
|
|
218
|
+
const ids = userIds.map((id) => id.trim()).filter(Boolean);
|
|
219
|
+
if (ids.length === 0 || !this.socket?.connected) {
|
|
220
|
+
return Promise.resolve([]);
|
|
221
|
+
}
|
|
222
|
+
return new Promise((resolve) => {
|
|
223
|
+
this.socket?.emit(AXP_REALTIME_SUBSCRIBE_PRESENCE, { userIds: ids }, (result) => {
|
|
224
|
+
resolve(Array.isArray(result?.items) ? result.items : []);
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
unsubscribePresence(userIds) {
|
|
229
|
+
const ids = userIds.map((id) => id.trim()).filter(Boolean);
|
|
230
|
+
if (ids.length === 0) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
this.socket?.emit(AXP_REALTIME_UNSUBSCRIBE_PRESENCE, { userIds: ids });
|
|
234
|
+
}
|
|
235
|
+
leavePresence() {
|
|
236
|
+
if (!this.socket?.connected) {
|
|
237
|
+
return Promise.resolve();
|
|
238
|
+
}
|
|
239
|
+
return new Promise((resolve) => {
|
|
240
|
+
const timer = setTimeout(resolve, 400);
|
|
241
|
+
this.socket?.emit(AXP_REALTIME_PRESENCE_LEAVE, {}, () => {
|
|
242
|
+
clearTimeout(timer);
|
|
243
|
+
resolve();
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
setPresence(status, source = 'manual') {
|
|
248
|
+
if (!this.socket?.connected) {
|
|
249
|
+
return Promise.resolve(undefined);
|
|
250
|
+
}
|
|
251
|
+
return new Promise((resolve) => {
|
|
252
|
+
this.socket?.emit(AXP_REALTIME_PRESENCE_SET, { status, source }, (result) => {
|
|
253
|
+
resolve(result?.ok ? result.item : undefined);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPRealtimeConnectionService, deps: [{ token: AXP_REALTIME_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
258
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPRealtimeConnectionService }); }
|
|
182
259
|
}
|
|
183
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
260
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPRealtimeConnectionService, decorators: [{
|
|
184
261
|
type: Injectable
|
|
185
262
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
186
263
|
type: Optional
|
|
@@ -189,8 +266,313 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
189
266
|
args: [AXP_REALTIME_CONFIG]
|
|
190
267
|
}] }] });
|
|
191
268
|
|
|
192
|
-
//#region
|
|
269
|
+
//#region ----- Constants -----
|
|
270
|
+
/** Idle without input before automatic Away. Keep in sync with server `AXP_USER_PRESENCE_IDLE_MS`. */
|
|
271
|
+
const AXP_USER_PRESENCE_IDLE_MS = 5 * 60_000;
|
|
272
|
+
//#endregion
|
|
273
|
+
|
|
274
|
+
//#region ----- Presence helpers -----
|
|
275
|
+
const PRESENCE_STATUSES = ['online', 'offline', 'away', 'busy'];
|
|
276
|
+
function isWatchablePresenceUserId(userId) {
|
|
277
|
+
const id = userId?.trim() ?? '';
|
|
278
|
+
if (!id || id === 'system') {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
return !id.startsWith('assist-');
|
|
282
|
+
}
|
|
283
|
+
function parseUserPresencePayload(payload) {
|
|
284
|
+
if (!payload || typeof payload !== 'object') {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
const raw = payload;
|
|
288
|
+
const userId = raw.userId?.trim();
|
|
289
|
+
if (!userId) {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
const status = PRESENCE_STATUSES.includes(raw.status) ? raw.status : 'offline';
|
|
293
|
+
const lastSeen = typeof raw.lastSeen === 'string' && raw.lastSeen.trim() ? raw.lastSeen.trim() : undefined;
|
|
294
|
+
const since = typeof raw.since === 'string' && raw.since.trim() ? raw.since.trim() : undefined;
|
|
295
|
+
const source = raw.source === 'auto' || raw.source === 'manual' ? raw.source : undefined;
|
|
296
|
+
return {
|
|
297
|
+
userId,
|
|
298
|
+
status,
|
|
299
|
+
...(lastSeen ? { lastSeen } : {}),
|
|
300
|
+
...(since ? { since } : {}),
|
|
301
|
+
...(source ? { source } : {}),
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
//#endregion
|
|
305
|
+
|
|
306
|
+
//#region ----- User presence store -----
|
|
307
|
+
const FLUSH_DEBOUNCE_MS = 40;
|
|
308
|
+
class AXPUserPresenceService {
|
|
309
|
+
//#endregion
|
|
310
|
+
constructor() {
|
|
311
|
+
//#region ----- Services & Dependencies -----
|
|
312
|
+
this.connection = inject(AXPRealtimeConnectionService, { optional: true });
|
|
313
|
+
//#endregion
|
|
314
|
+
//#region ----- State -----
|
|
315
|
+
this.presenceByUserId = new Map();
|
|
316
|
+
this.watchCounts = new Map();
|
|
317
|
+
this.subjects = new Map();
|
|
318
|
+
this.updatesSubject = new Subject();
|
|
319
|
+
this.flushTimer = null;
|
|
320
|
+
this.pendingSubscribe = new Set();
|
|
321
|
+
this.pendingUnsubscribe = new Set();
|
|
322
|
+
this.updates$ = this.updatesSubject.asObservable();
|
|
323
|
+
this.connection?.connectionStatus$.subscribe((status) => {
|
|
324
|
+
if (status === 'connected') {
|
|
325
|
+
this.resubscribeAll();
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
//#region ----- Public API -----
|
|
330
|
+
get(userId) {
|
|
331
|
+
const id = userId?.trim();
|
|
332
|
+
if (!id) {
|
|
333
|
+
return undefined;
|
|
334
|
+
}
|
|
335
|
+
return this.presenceByUserId.get(id);
|
|
336
|
+
}
|
|
337
|
+
presence$(userId) {
|
|
338
|
+
const id = userId?.trim();
|
|
339
|
+
const fallback = { userId: id, status: 'offline' };
|
|
340
|
+
if (!id) {
|
|
341
|
+
return new BehaviorSubject(fallback).asObservable();
|
|
342
|
+
}
|
|
343
|
+
let subject = this.subjects.get(id);
|
|
344
|
+
if (!subject) {
|
|
345
|
+
subject = new BehaviorSubject(this.presenceByUserId.get(id) ?? fallback);
|
|
346
|
+
this.subjects.set(id, subject);
|
|
347
|
+
}
|
|
348
|
+
return subject.asObservable();
|
|
349
|
+
}
|
|
350
|
+
watch(userId) {
|
|
351
|
+
if (!isWatchablePresenceUserId(userId)) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const id = userId.trim();
|
|
355
|
+
const next = (this.watchCounts.get(id) ?? 0) + 1;
|
|
356
|
+
this.watchCounts.set(id, next);
|
|
357
|
+
if (next === 1) {
|
|
358
|
+
this.pendingUnsubscribe.delete(id);
|
|
359
|
+
this.pendingSubscribe.add(id);
|
|
360
|
+
this.scheduleFlush();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
watchMany(userIds) {
|
|
364
|
+
for (const userId of userIds) {
|
|
365
|
+
this.watch(userId);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
/** Watch only if this user is not already in the local watch set. */
|
|
369
|
+
ensureWatch(userId) {
|
|
370
|
+
const id = userId?.trim();
|
|
371
|
+
if (!id || (this.watchCounts.get(id) ?? 0) > 0) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
this.watch(id);
|
|
375
|
+
}
|
|
376
|
+
ensureWatchMany(userIds) {
|
|
377
|
+
for (const userId of userIds) {
|
|
378
|
+
this.ensureWatch(userId);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
unwatch(userId) {
|
|
382
|
+
const id = userId?.trim();
|
|
383
|
+
if (!id) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
const current = this.watchCounts.get(id) ?? 0;
|
|
387
|
+
if (current <= 1) {
|
|
388
|
+
this.watchCounts.delete(id);
|
|
389
|
+
this.pendingSubscribe.delete(id);
|
|
390
|
+
this.pendingUnsubscribe.add(id);
|
|
391
|
+
this.scheduleFlush();
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
this.watchCounts.set(id, current - 1);
|
|
395
|
+
}
|
|
396
|
+
applySnapshot(items) {
|
|
397
|
+
for (const item of items) {
|
|
398
|
+
this.applyPresence(item);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
applyEnvelopePayload(payload) {
|
|
402
|
+
const parsed = parseUserPresencePayload(payload);
|
|
403
|
+
if (parsed) {
|
|
404
|
+
this.applyPresence(parsed);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
async setAvailability(status, source = 'manual') {
|
|
408
|
+
const item = await this.connection?.setPresence(status, source);
|
|
409
|
+
if (item) {
|
|
410
|
+
this.applyPresence(item);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
//#endregion
|
|
414
|
+
//#region ----- Store updates -----
|
|
415
|
+
applyPresence(presence) {
|
|
416
|
+
const previous = this.presenceByUserId.get(presence.userId);
|
|
417
|
+
if (previous &&
|
|
418
|
+
previous.status === presence.status &&
|
|
419
|
+
previous.lastSeen === presence.lastSeen &&
|
|
420
|
+
previous.since === presence.since) {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
this.presenceByUserId.set(presence.userId, presence);
|
|
424
|
+
const subject = this.subjects.get(presence.userId);
|
|
425
|
+
if (subject && !subject.closed) {
|
|
426
|
+
subject.next(presence);
|
|
427
|
+
}
|
|
428
|
+
this.updatesSubject.next(presence);
|
|
429
|
+
}
|
|
430
|
+
scheduleFlush() {
|
|
431
|
+
if (this.flushTimer) {
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
this.flushTimer = setTimeout(() => {
|
|
435
|
+
this.flushTimer = null;
|
|
436
|
+
void this.flush();
|
|
437
|
+
}, FLUSH_DEBOUNCE_MS);
|
|
438
|
+
}
|
|
439
|
+
async flush() {
|
|
440
|
+
const subscribeIds = Array.from(this.pendingSubscribe);
|
|
441
|
+
const unsubscribeIds = Array.from(this.pendingUnsubscribe);
|
|
442
|
+
this.pendingSubscribe.clear();
|
|
443
|
+
this.pendingUnsubscribe.clear();
|
|
444
|
+
if (unsubscribeIds.length > 0) {
|
|
445
|
+
this.connection?.unsubscribePresence(unsubscribeIds);
|
|
446
|
+
}
|
|
447
|
+
if (subscribeIds.length === 0) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
const items = (await this.connection?.subscribePresence(subscribeIds)) ?? [];
|
|
451
|
+
this.applySnapshot(items);
|
|
452
|
+
}
|
|
453
|
+
resubscribeAll() {
|
|
454
|
+
const watched = Array.from(this.watchCounts.keys());
|
|
455
|
+
if (watched.length === 0) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
this.pendingUnsubscribe.clear();
|
|
459
|
+
for (const id of watched) {
|
|
460
|
+
this.pendingSubscribe.add(id);
|
|
461
|
+
}
|
|
462
|
+
this.scheduleFlush();
|
|
463
|
+
}
|
|
464
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserPresenceService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
465
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserPresenceService, providedIn: 'root' }); }
|
|
466
|
+
}
|
|
467
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserPresenceService, decorators: [{
|
|
468
|
+
type: Injectable,
|
|
469
|
+
args: [{ providedIn: 'root' }]
|
|
470
|
+
}], ctorParameters: () => [] });
|
|
471
|
+
|
|
472
|
+
//#region ----- Automatic away from idle -----
|
|
473
|
+
const IDLE_CHECK_MS = 15_000;
|
|
474
|
+
const ACTIVITY_THROTTLE_MS = 1_000;
|
|
475
|
+
class AXPUserPresenceIdleService {
|
|
476
|
+
//#endregion
|
|
477
|
+
constructor() {
|
|
478
|
+
//#region ----- Services & Dependencies -----
|
|
479
|
+
this.document = inject(DOCUMENT);
|
|
480
|
+
this.session = inject(AXPSessionService);
|
|
481
|
+
this.presence = inject(AXPUserPresenceService);
|
|
482
|
+
this.destroyRef = inject(DestroyRef);
|
|
483
|
+
//#endregion
|
|
484
|
+
//#region ----- State -----
|
|
485
|
+
this.lastActivityAt = Date.now();
|
|
486
|
+
this.lastActivityEmitAt = 0;
|
|
487
|
+
this.idle = false;
|
|
488
|
+
this.checkTimer = null;
|
|
489
|
+
this.started = false;
|
|
490
|
+
//#endregion
|
|
491
|
+
//#region ----- Activity -----
|
|
492
|
+
this.onActivity = () => {
|
|
493
|
+
const now = Date.now();
|
|
494
|
+
this.lastActivityAt = now;
|
|
495
|
+
if (now - this.lastActivityEmitAt < ACTIVITY_THROTTLE_MS) {
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
this.lastActivityEmitAt = now;
|
|
499
|
+
if (this.idle) {
|
|
500
|
+
this.idle = false;
|
|
501
|
+
void this.presence.setAvailability('online', 'auto');
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
this.onVisibility = () => {
|
|
505
|
+
if (!this.document.hidden) {
|
|
506
|
+
this.onActivity();
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
this.session.status$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((status) => {
|
|
510
|
+
if (status === AXPSessionStatus.Authorized) {
|
|
511
|
+
this.start();
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
this.stop();
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
//#region ----- Lifecycle -----
|
|
518
|
+
start() {
|
|
519
|
+
if (this.started) {
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
this.started = true;
|
|
523
|
+
this.lastActivityAt = Date.now();
|
|
524
|
+
this.idle = false;
|
|
525
|
+
const target = this.document.defaultView ?? this.document;
|
|
526
|
+
target.addEventListener('mousemove', this.onActivity, { passive: true });
|
|
527
|
+
target.addEventListener('keydown', this.onActivity, { passive: true });
|
|
528
|
+
target.addEventListener('mousedown', this.onActivity, { passive: true });
|
|
529
|
+
target.addEventListener('touchstart', this.onActivity, { passive: true });
|
|
530
|
+
this.document.addEventListener('visibilitychange', this.onVisibility);
|
|
531
|
+
this.checkTimer = setInterval(() => this.checkIdle(), IDLE_CHECK_MS);
|
|
532
|
+
}
|
|
533
|
+
stop() {
|
|
534
|
+
if (!this.started) {
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
this.started = false;
|
|
538
|
+
this.idle = false;
|
|
539
|
+
const target = this.document.defaultView ?? this.document;
|
|
540
|
+
target.removeEventListener('mousemove', this.onActivity);
|
|
541
|
+
target.removeEventListener('keydown', this.onActivity);
|
|
542
|
+
target.removeEventListener('mousedown', this.onActivity);
|
|
543
|
+
target.removeEventListener('touchstart', this.onActivity);
|
|
544
|
+
this.document.removeEventListener('visibilitychange', this.onVisibility);
|
|
545
|
+
if (this.checkTimer) {
|
|
546
|
+
clearInterval(this.checkTimer);
|
|
547
|
+
this.checkTimer = null;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
checkIdle() {
|
|
551
|
+
if (!this.started || this.idle) {
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
if (Date.now() - this.lastActivityAt < AXP_USER_PRESENCE_IDLE_MS) {
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
this.idle = true;
|
|
558
|
+
void this.presence.setAvailability('away', 'auto');
|
|
559
|
+
}
|
|
560
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserPresenceIdleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
561
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserPresenceIdleService, providedIn: 'root' }); }
|
|
562
|
+
}
|
|
563
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserPresenceIdleService, decorators: [{
|
|
564
|
+
type: Injectable,
|
|
565
|
+
args: [{ providedIn: 'root' }]
|
|
566
|
+
}], ctorParameters: () => [] });
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Registers built-in always-on realtime (Socket.IO) + topic dispatcher.
|
|
570
|
+
*/
|
|
193
571
|
function provideRealtime(config = {}) {
|
|
572
|
+
const backend = config.backend ?? 'builtin';
|
|
573
|
+
if (backend !== 'builtin') {
|
|
574
|
+
throw new Error(`Unsupported realtime backend '${String(backend)}'. Use 'builtin'.`);
|
|
575
|
+
}
|
|
194
576
|
const url = config.url?.trim() ||
|
|
195
577
|
(config.apiBaseUrl?.trim() ? resolveRealtimeSocketUrl(config.apiBaseUrl) : undefined);
|
|
196
578
|
return makeEnvironmentProviders([
|
|
@@ -204,24 +586,79 @@ function provideRealtime(config = {}) {
|
|
|
204
586
|
AXPRealtimeDispatcherService,
|
|
205
587
|
AXPRealtimeConnectionService,
|
|
206
588
|
{
|
|
207
|
-
provide:
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
589
|
+
provide: AXPRealtimeConnectionPort,
|
|
590
|
+
useExisting: AXPRealtimeConnectionService,
|
|
591
|
+
},
|
|
592
|
+
provideCommandSetups([
|
|
593
|
+
{
|
|
594
|
+
key: PRESENCE_SET_AVAILABILITY,
|
|
595
|
+
command: () => import('./acorex-platform-framework-client-realtime-set-presence-availability.command-CetlUjnM.mjs').then((c) => c.AXPSetPresenceAvailabilityCommand),
|
|
596
|
+
},
|
|
597
|
+
]),
|
|
598
|
+
provideAppStartUpTask(() => {
|
|
599
|
+
inject(AXPUserPresenceIdleService);
|
|
600
|
+
return {
|
|
601
|
+
name: 'user-presence-idle',
|
|
602
|
+
priority: AXP_APP_STARTUP_PRIORITY.realtimeSubscriptions,
|
|
603
|
+
run: async () => undefined,
|
|
604
|
+
};
|
|
605
|
+
}),
|
|
606
|
+
provideAppStartUpTask(() => {
|
|
607
|
+
const dispatcher = inject(AXPRealtimeDispatcherService);
|
|
608
|
+
const presence = inject(AXPUserPresenceService);
|
|
609
|
+
return {
|
|
610
|
+
name: 'user-presence-handler',
|
|
611
|
+
priority: AXP_APP_STARTUP_PRIORITY.realtimeHandlers,
|
|
612
|
+
run: async () => {
|
|
613
|
+
dispatcher.register({
|
|
614
|
+
topic: AXP_REALTIME_TOPIC_USER_PRESENCE,
|
|
615
|
+
handle: (envelope) => {
|
|
616
|
+
presence.applyEnvelopePayload(envelope.payload);
|
|
617
|
+
},
|
|
618
|
+
});
|
|
619
|
+
},
|
|
620
|
+
};
|
|
621
|
+
}),
|
|
622
|
+
provideAppStartUpTask(() => {
|
|
623
|
+
const connection = inject(AXPRealtimeConnectionPort);
|
|
624
|
+
return {
|
|
625
|
+
name: 'realtime-connect',
|
|
626
|
+
priority: AXP_APP_STARTUP_PRIORITY.realtimeConnect,
|
|
627
|
+
run: async () => {
|
|
628
|
+
// Connection lifecycle is owned by the connection service (session.status$).
|
|
213
629
|
// Eagerly invoke connect once so an already-authenticated session connects on bootstrap.
|
|
214
630
|
connection.connect();
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
},
|
|
631
|
+
},
|
|
632
|
+
};
|
|
633
|
+
}),
|
|
218
634
|
]);
|
|
219
635
|
}
|
|
220
636
|
//#endregion
|
|
221
637
|
|
|
638
|
+
//#endregion
|
|
639
|
+
|
|
640
|
+
//#region ----- Presence duration tooltip -----
|
|
641
|
+
function presenceDurationBucket(ms) {
|
|
642
|
+
const elapsed = Math.max(0, ms);
|
|
643
|
+
if (elapsed < 60_000) {
|
|
644
|
+
return { key: 'duration.less-than-a-minute' };
|
|
645
|
+
}
|
|
646
|
+
const minutes = Math.floor(elapsed / 60_000);
|
|
647
|
+
if (minutes < 60) {
|
|
648
|
+
return minutes === 1 ? { key: 'duration.one-minute' } : { key: 'duration.minutes', params: { count: minutes } };
|
|
649
|
+
}
|
|
650
|
+
const hours = Math.floor(minutes / 60);
|
|
651
|
+
if (hours < 24) {
|
|
652
|
+
return hours === 1 ? { key: 'duration.one-hour' } : { key: 'duration.hours', params: { count: hours } };
|
|
653
|
+
}
|
|
654
|
+
const days = Math.floor(hours / 24);
|
|
655
|
+
return days === 1 ? { key: 'duration.one-day' } : { key: 'duration.days', params: { count: days } };
|
|
656
|
+
}
|
|
657
|
+
//#endregion
|
|
658
|
+
|
|
222
659
|
/**
|
|
223
660
|
* Generated bundle index. Do not edit.
|
|
224
661
|
*/
|
|
225
662
|
|
|
226
|
-
export { AXPRealtimeConnectionService, AXPRealtimeDispatcherService, AXP_REALTIME_CONFIG, AXP_REALTIME_SOCKET_EVENT, AXP_REALTIME_SUBSCRIBE_CONVERSATION, AXP_REALTIME_TOPIC_CONVERSATION_MESSAGE, AXP_REALTIME_TOPIC_ENTITY_MUTATION, AXP_REALTIME_TOPIC_HANDLER, AXP_REALTIME_TOPIC_INBOX_REFRESH, AXP_REALTIME_UNSUBSCRIBE_CONVERSATION, provideRealtime, resolveRealtimeSocketUrl };
|
|
663
|
+
export { AXPRealtimeConnectionPort, AXPRealtimeConnectionService, AXPRealtimeDispatcherService, AXPUserPresenceIdleService, AXPUserPresenceService, AXP_REALTIME_CONFIG, AXP_REALTIME_EMIT_TYPING, AXP_REALTIME_PRESENCE_LEAVE, AXP_REALTIME_PRESENCE_SET, AXP_REALTIME_SOCKET_EVENT, AXP_REALTIME_SUBSCRIBE_CONVERSATION, AXP_REALTIME_SUBSCRIBE_PRESENCE, AXP_REALTIME_TOPIC_CONVERSATION_CALL, AXP_REALTIME_TOPIC_CONVERSATION_MESSAGE, AXP_REALTIME_TOPIC_CONVERSATION_TYPING, AXP_REALTIME_TOPIC_ENTITY_MUTATION, AXP_REALTIME_TOPIC_HANDLER, AXP_REALTIME_TOPIC_INBOX_REFRESH, AXP_REALTIME_TOPIC_USER_PRESENCE, AXP_REALTIME_UNSUBSCRIBE_CONVERSATION, AXP_REALTIME_UNSUBSCRIBE_PRESENCE, AXP_USER_PRESENCE_IDLE_MS, isWatchablePresenceUserId, parseUserPresencePayload, presenceDurationBucket, provideRealtime, resolveRealtimeSocketUrl };
|
|
227
664
|
//# sourceMappingURL=acorex-platform-framework-client-realtime.mjs.map
|