metag-sdk-ionic 1.2.7-dev-0.60 → 1.2.7-dev-0.61
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/dist/src/app/pages/id-vision/components/camara-video-selfie/camara-video-selfie.component.js +405 -405
- package/dist/src/app/pages/id-vision/components/direct-photo-selfie/direct-photo-selfie.component.d.ts +37 -37
- package/dist/src/app/pages/id-vision/components/direct-photo-selfie/direct-photo-selfie.component.js +204 -204
- package/dist/src/app/pages/id-vision/components/photo-selfie-camera/photo-selfie-camera.component.d.ts +48 -48
- package/dist/src/app/pages/id-vision/components/photo-selfie-camera/photo-selfie-camera.component.js +261 -261
- package/dist/src/app/pages/id-vision/components/simple-acuerdo-video/simple-acuerdo-video.component.js +480 -480
- package/dist/src/app/pages/id-vision/id-vision.component.d.ts +122 -122
- package/dist/src/app/pages/id-vision/id-vision.component.js +1414 -1414
- package/dist/src/app/pages/id-vision/id-vision.component.js.map +1 -1
- package/dist/src/app/pages/id-vision/services/configuration/configuration.service.js +1 -0
- package/dist/src/app/pages/id-vision/services/configuration/configuration.service.js.map +1 -1
- package/dist/src/app/pages/id-vision/services/modal-services/sdk-communication-services.js +21 -21
- package/package.json +1 -1
package/dist/src/app/pages/id-vision/components/camara-video-selfie/camara-video-selfie.component.js
CHANGED
|
@@ -1,406 +1,406 @@
|
|
|
1
|
-
import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core';
|
|
2
|
-
import { Camera } from '@capacitor/camera';
|
|
3
|
-
import { ScreenBrightness } from '@capacitor-community/screen-brightness';
|
|
4
|
-
import { Capacitor } from '@capacitor/core';
|
|
5
|
-
import { App } from '@capacitor/app';
|
|
6
|
-
import * as i0 from "@angular/core";
|
|
7
|
-
import * as i1 from "@ionic/angular";
|
|
8
|
-
import * as i2 from "@angular/platform-browser";
|
|
9
|
-
import * as i3 from "../../services/modal-services/modal-video-selfie-services";
|
|
10
|
-
import * as i4 from "../../services/modal-services/modal-dpi-services";
|
|
11
|
-
import * as i5 from "@angular/common";
|
|
12
|
-
const _c0 = ["videoElement"];
|
|
13
|
-
const _c1 = ["progressRing"];
|
|
14
|
-
const _c2 = a0 => ({ "red": a0 });
|
|
15
|
-
function CamaraVideoSelfieComponent_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
16
|
-
i0.ɵɵelementStart(0, "div", 19)(1, "div", 20);
|
|
17
|
-
i0.ɵɵtext(2);
|
|
18
|
-
i0.ɵɵelementEnd()();
|
|
19
|
-
} if (rf & 2) {
|
|
20
|
-
const ctx_r1 = i0.ɵɵnextContext();
|
|
21
|
-
i0.ɵɵadvance(2);
|
|
22
|
-
i0.ɵɵtextInterpolate(ctx_r1.countdown);
|
|
23
|
-
} }
|
|
24
|
-
function CamaraVideoSelfieComponent_ion_button_19_Template(rf, ctx) { if (rf & 1) {
|
|
25
|
-
const _r3 = i0.ɵɵgetCurrentView();
|
|
26
|
-
i0.ɵɵelementStart(0, "ion-button", 21);
|
|
27
|
-
i0.ɵɵlistener("click", function CamaraVideoSelfieComponent_ion_button_19_Template_ion_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.recordVideo()); });
|
|
28
|
-
i0.ɵɵtext(1, "Iniciar Grabaci\u00F3n");
|
|
29
|
-
i0.ɵɵelementEnd();
|
|
30
|
-
} }
|
|
31
|
-
function CamaraVideoSelfieComponent_ion_button_20_Template(rf, ctx) { if (rf & 1) {
|
|
32
|
-
const _r4 = i0.ɵɵgetCurrentView();
|
|
33
|
-
i0.ɵɵelementStart(0, "ion-button", 22);
|
|
34
|
-
i0.ɵɵlistener("click", function CamaraVideoSelfieComponent_ion_button_20_Template_ion_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.stopRecording()); });
|
|
35
|
-
i0.ɵɵtext(1, "Detener Grabaci\u00F3n");
|
|
36
|
-
i0.ɵɵelementEnd();
|
|
37
|
-
} if (rf & 2) {
|
|
38
|
-
const ctx_r1 = i0.ɵɵnextContext();
|
|
39
|
-
i0.ɵɵproperty("disabled", !ctx_r1.canStopRecording);
|
|
40
|
-
} }
|
|
41
|
-
export class CamaraVideoSelfieComponent {
|
|
42
|
-
constructor(platform, modalController, sanitizer, renderer, alertController, changeDetector, modalVideoSelfieServices, modalDpiServices) {
|
|
43
|
-
this.platform = platform;
|
|
44
|
-
this.modalController = modalController;
|
|
45
|
-
this.sanitizer = sanitizer;
|
|
46
|
-
this.renderer = renderer;
|
|
47
|
-
this.alertController = alertController;
|
|
48
|
-
this.changeDetector = changeDetector;
|
|
49
|
-
this.modalVideoSelfieServices = modalVideoSelfieServices;
|
|
50
|
-
this.modalDpiServices = modalDpiServices;
|
|
51
|
-
this.text1 = '';
|
|
52
|
-
this.text2 = '';
|
|
53
|
-
this.closeRequested = new EventEmitter();
|
|
54
|
-
this.stream = null;
|
|
55
|
-
this.isRecording = false;
|
|
56
|
-
this.mediaRecorder = null;
|
|
57
|
-
this.recordedChunks = [];
|
|
58
|
-
this.countdown = 0;
|
|
59
|
-
this.minRecordingTime = 3000;
|
|
60
|
-
this.maxRecordingTime = 5000;
|
|
61
|
-
this.timeRemaining = this.maxRecordingTime / 1000;
|
|
62
|
-
this.canStopRecording = true;
|
|
63
|
-
this.isLoading = true;
|
|
64
|
-
this.defaultBrightness = null;
|
|
65
|
-
this.isAndroid = this.platform.is('android');
|
|
66
|
-
this.isIOS = this.platform.is('ios');
|
|
67
|
-
}
|
|
68
|
-
async ngAfterViewInit() {
|
|
69
|
-
if (this.isAndroid || this.isIOS) {
|
|
70
|
-
try {
|
|
71
|
-
const { brightness } = await ScreenBrightness.getBrightness();
|
|
72
|
-
this.defaultBrightness = brightness;
|
|
73
|
-
await ScreenBrightness.setBrightness({ brightness: 1.0 });
|
|
74
|
-
}
|
|
75
|
-
catch (error) {
|
|
76
|
-
console.warn('Brillo error:', error);
|
|
77
|
-
}
|
|
78
|
-
await this.requestPermissions();
|
|
79
|
-
// 🔹 Listener para detectar cuando la app va a segundo plano
|
|
80
|
-
this.appStateListener = await App.addListener('appStateChange', async (state) => {
|
|
81
|
-
console.log('🔄 [VideoSelfie] App state changed:', state.isActive);
|
|
82
|
-
if (!state.isActive) {
|
|
83
|
-
console.log('⏸️ [VideoSelfie] App fue a background, cancelando grabación...');
|
|
84
|
-
await this.handleAppBackground();
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
console.log('✅ [VideoSelfie] App volvió al foreground, reiniciando cámara...');
|
|
88
|
-
await this.handleAppForeground();
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
await this.initCamera();
|
|
93
|
-
await this.waitForCameraReady();
|
|
94
|
-
this.modalDpiServices.closeModalAndChangeBrightness$.subscribe(async () => await this.closeOverlayVideo());
|
|
95
|
-
}
|
|
96
|
-
async ngOnDestroy() {
|
|
97
|
-
if (this.appStateListener) {
|
|
98
|
-
await this.appStateListener.remove();
|
|
99
|
-
}
|
|
100
|
-
this.cleanupTimers();
|
|
101
|
-
this.stopCamera();
|
|
102
|
-
if (this.defaultBrightness !== null) {
|
|
103
|
-
await ScreenBrightness.setBrightness({ brightness: this.defaultBrightness });
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
async handleAppBackground() {
|
|
107
|
-
// Si está grabando o en countdown, cancelar todo
|
|
108
|
-
if (this.isRecording || this.countdown > 0) {
|
|
109
|
-
console.log('⚠️ [VideoSelfie] Grabación/Countdown en progreso, cancelando...');
|
|
110
|
-
await this.cancelRecording();
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
async handleAppForeground() {
|
|
114
|
-
// Reiniciar la cámara completamente
|
|
115
|
-
console.log('🔄 [VideoSelfie] Reiniciando cámara...');
|
|
116
|
-
this.isLoading = true;
|
|
117
|
-
this.changeDetector.detectChanges();
|
|
118
|
-
// Detener la cámara actual si existe
|
|
119
|
-
this.stopCamera();
|
|
120
|
-
// Reiniciar
|
|
121
|
-
await this.initCamera();
|
|
122
|
-
await this.waitForCameraReady();
|
|
123
|
-
this.isLoading = false;
|
|
124
|
-
this.changeDetector.detectChanges();
|
|
125
|
-
console.log('✅ [VideoSelfie] Cámara reiniciada, lista para grabar');
|
|
126
|
-
}
|
|
127
|
-
async cancelRecording() {
|
|
128
|
-
console.log('🚫 [VideoSelfie] Cancelando grabación...');
|
|
129
|
-
// Limpiar countdown
|
|
130
|
-
if (this.countdownInterval) {
|
|
131
|
-
clearInterval(this.countdownInterval);
|
|
132
|
-
this.countdownInterval = null;
|
|
133
|
-
}
|
|
134
|
-
this.countdown = 0;
|
|
135
|
-
// Detener grabación si está activa
|
|
136
|
-
if (this.mediaRecorder && this.isRecording) {
|
|
137
|
-
if (this.mediaRecorder.state !== 'inactive') {
|
|
138
|
-
this.mediaRecorder.stop();
|
|
139
|
-
}
|
|
140
|
-
this.isRecording = false;
|
|
141
|
-
}
|
|
142
|
-
// Limpiar timer de grabación
|
|
143
|
-
if (this.recordingTimer) {
|
|
144
|
-
clearTimeout(this.recordingTimer);
|
|
145
|
-
this.recordingTimer = null;
|
|
146
|
-
}
|
|
147
|
-
// Limpiar chunks grabados (no enviar video incompleto)
|
|
148
|
-
this.recordedChunks = [];
|
|
149
|
-
// Remover clase de progreso
|
|
150
|
-
if (this.progressRing) {
|
|
151
|
-
this.renderer.removeClass(this.progressRing.nativeElement, 'progress-active');
|
|
152
|
-
}
|
|
153
|
-
this.canStopRecording = true;
|
|
154
|
-
this.timeRemaining = this.maxRecordingTime / 1000;
|
|
155
|
-
this.changeDetector.detectChanges();
|
|
156
|
-
console.log('✅ [VideoSelfie] Grabación cancelada, no se enviará video');
|
|
157
|
-
}
|
|
158
|
-
cleanupTimers() {
|
|
159
|
-
if (this.recordingTimer) {
|
|
160
|
-
clearTimeout(this.recordingTimer);
|
|
161
|
-
this.recordingTimer = null;
|
|
162
|
-
}
|
|
163
|
-
if (this.countdownInterval) {
|
|
164
|
-
clearInterval(this.countdownInterval);
|
|
165
|
-
this.countdownInterval = null;
|
|
166
|
-
}
|
|
167
|
-
if (this.scanTimeout) {
|
|
168
|
-
clearTimeout(this.scanTimeout);
|
|
169
|
-
this.scanTimeout = null;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
async requestPermissions() {
|
|
173
|
-
if (Capacitor.getPlatform() !== 'web') {
|
|
174
|
-
if (this.isAndroid || this.isIOS) {
|
|
175
|
-
const permissions = await Camera.requestPermissions();
|
|
176
|
-
if (permissions.camera === 'denied') {
|
|
177
|
-
console.error('Permiso de cámara denegado');
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
async initCamera() {
|
|
184
|
-
try {
|
|
185
|
-
const constraints = {
|
|
186
|
-
audio: false,
|
|
187
|
-
video: {
|
|
188
|
-
facingMode: 'user',
|
|
189
|
-
width: { ideal: 640 }, // Fuerza resolución estándar
|
|
190
|
-
height: { ideal: 480 },
|
|
191
|
-
aspectRatio: 4 / 3
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
this.stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
195
|
-
const video = this.videoElement.nativeElement;
|
|
196
|
-
video.srcObject = this.stream;
|
|
197
|
-
video.setAttribute('playsinline', 'true');
|
|
198
|
-
video.muted = true;
|
|
199
|
-
// ⏳ Esperar un poco antes de reproducir para evitar salto de lente
|
|
200
|
-
await new Promise((res) => setTimeout(res, 300));
|
|
201
|
-
await video.play();
|
|
202
|
-
this.isLoading = false;
|
|
203
|
-
await this.prepareRecorder();
|
|
204
|
-
}
|
|
205
|
-
catch (error) {
|
|
206
|
-
console.error('initCamera error:', error);
|
|
207
|
-
this.isLoading = false;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
async waitForCameraReady() {
|
|
211
|
-
const video = this.videoElement.nativeElement;
|
|
212
|
-
return new Promise((resolve) => {
|
|
213
|
-
if (video.readyState >= 3) {
|
|
214
|
-
resolve();
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
video.onloadedmetadata = () => resolve();
|
|
218
|
-
}
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
async prepareRecorder() {
|
|
222
|
-
if (!this.stream || !this.stream.getVideoTracks().length)
|
|
223
|
-
return;
|
|
224
|
-
let mimeType = '';
|
|
225
|
-
if (this.isIOS && MediaRecorder.isTypeSupported('video/mp4')) {
|
|
226
|
-
mimeType = 'video/mp4';
|
|
227
|
-
}
|
|
228
|
-
else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
|
|
229
|
-
mimeType = 'video/webm;codecs=vp8';
|
|
230
|
-
}
|
|
231
|
-
else if (MediaRecorder.isTypeSupported('video/webm')) {
|
|
232
|
-
mimeType = 'video/webm';
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
alert('Formato no soportado');
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
const options = {
|
|
239
|
-
mimeType,
|
|
240
|
-
videoBitsPerSecond: 400_000,
|
|
241
|
-
};
|
|
242
|
-
this.mediaRecorder = new MediaRecorder(this.stream, options);
|
|
243
|
-
this.recordedChunks = [];
|
|
244
|
-
this.mediaRecorder.ondataavailable = (event) => {
|
|
245
|
-
if (event.data?.size > 0)
|
|
246
|
-
this.recordedChunks.push(event.data);
|
|
247
|
-
};
|
|
248
|
-
this.mediaRecorder.onerror = (event) => {
|
|
249
|
-
console.error('Recorder error:', event);
|
|
250
|
-
alert('Error grabando video');
|
|
251
|
-
};
|
|
252
|
-
this.mediaRecorder.onstop = async () => {
|
|
253
|
-
if (!this.recordedChunks.length)
|
|
254
|
-
return;
|
|
255
|
-
const fileExtension = mimeType.includes('webm') ? 'webm' : 'mp4';
|
|
256
|
-
const blob = new Blob(this.recordedChunks, { type: mimeType });
|
|
257
|
-
const file = this.blobToFile(blob, `video-selfie.${fileExtension}`);
|
|
258
|
-
this.capVideo = file;
|
|
259
|
-
if (this.backFunction)
|
|
260
|
-
await this.backFunction(file);
|
|
261
|
-
this.recordedChunks = [];
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
recordVideo() {
|
|
265
|
-
this.countdown = 3;
|
|
266
|
-
this.countdownInterval = setInterval(() => {
|
|
267
|
-
this.countdown -= 1;
|
|
268
|
-
if (this.countdown <= 0) {
|
|
269
|
-
clearInterval(this.countdownInterval);
|
|
270
|
-
this.countdownInterval = null;
|
|
271
|
-
this.startVideoRecord();
|
|
272
|
-
}
|
|
273
|
-
this.changeDetector.detectChanges();
|
|
274
|
-
}, 1000);
|
|
275
|
-
}
|
|
276
|
-
async startVideoRecord() {
|
|
277
|
-
if (this.mediaRecorder && !this.isRecording) {
|
|
278
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
279
|
-
this.mediaRecorder.start();
|
|
280
|
-
this.isRecording = true;
|
|
281
|
-
this.canStopRecording = false;
|
|
282
|
-
this.renderer.addClass(this.progressRing.nativeElement, 'progress-active');
|
|
283
|
-
this.timeRemaining = this.maxRecordingTime / 1000;
|
|
284
|
-
this.updateTimeRemaining();
|
|
285
|
-
this.recordingTimer = setTimeout(async () => {
|
|
286
|
-
this.canStopRecording = true;
|
|
287
|
-
await this.stopRecording();
|
|
288
|
-
}, this.maxRecordingTime);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
updateTimeRemaining() {
|
|
292
|
-
const timer = setInterval(() => {
|
|
293
|
-
if (this.isRecording) {
|
|
294
|
-
this.timeRemaining -= 1;
|
|
295
|
-
if (this.timeRemaining <= 0)
|
|
296
|
-
clearInterval(timer);
|
|
297
|
-
}
|
|
298
|
-
else {
|
|
299
|
-
clearInterval(timer);
|
|
300
|
-
}
|
|
301
|
-
this.changeDetector.detectChanges();
|
|
302
|
-
}, 1000);
|
|
303
|
-
}
|
|
304
|
-
async stopRecording() {
|
|
305
|
-
if (this.mediaRecorder && this.isRecording && this.canStopRecording) {
|
|
306
|
-
if (this.mediaRecorder.state !== 'inactive')
|
|
307
|
-
this.mediaRecorder.stop();
|
|
308
|
-
this.isRecording = false;
|
|
309
|
-
}
|
|
310
|
-
if (this.scanTimeout)
|
|
311
|
-
clearTimeout(this.scanTimeout);
|
|
312
|
-
this.renderer.removeClass(this.progressRing.nativeElement, 'progress-active');
|
|
313
|
-
}
|
|
314
|
-
blobToFile(blob, fileName) {
|
|
315
|
-
const b = blob;
|
|
316
|
-
b.lastModified = Date.now();
|
|
317
|
-
b.lastModifiedDate = new Date();
|
|
318
|
-
b.name = fileName;
|
|
319
|
-
return b;
|
|
320
|
-
}
|
|
321
|
-
async closeOverlayVideo() {
|
|
322
|
-
this.stopCamera();
|
|
323
|
-
if (this.defaultBrightness !== null) {
|
|
324
|
-
await ScreenBrightness.setBrightness({ brightness: this.defaultBrightness });
|
|
325
|
-
}
|
|
326
|
-
this.modalController.dismiss();
|
|
327
|
-
}
|
|
328
|
-
stopCamera() {
|
|
329
|
-
if (this.stream) {
|
|
330
|
-
this.stream.getTracks().forEach((track) => track.stop());
|
|
331
|
-
this.stream = null;
|
|
332
|
-
}
|
|
333
|
-
if (this.scanTimeout)
|
|
334
|
-
clearTimeout(this.scanTimeout);
|
|
335
|
-
}
|
|
336
|
-
closeRequestedFunction() {
|
|
337
|
-
this.closeOverlayVideo();
|
|
338
|
-
this.modalDpiServices.requestCloseModalAndBrightness();
|
|
339
|
-
}
|
|
340
|
-
static { this.ɵfac = function CamaraVideoSelfieComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CamaraVideoSelfieComponent)(i0.ɵɵdirectiveInject(i1.Platform), i0.ɵɵdirectiveInject(i1.ModalController), i0.ɵɵdirectiveInject(i2.DomSanitizer), i0.ɵɵdirectiveInject(i0.Renderer2), i0.ɵɵdirectiveInject(i1.AlertController), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i3.ModalVideoSelfieServices), i0.ɵɵdirectiveInject(i4.ModalDpiServices)); }; }
|
|
341
|
-
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CamaraVideoSelfieComponent, selectors: [["app-camara-video-selfie"]], viewQuery: function CamaraVideoSelfieComponent_Query(rf, ctx) { if (rf & 1) {
|
|
342
|
-
i0.ɵɵviewQuery(_c0, 5);
|
|
343
|
-
i0.ɵɵviewQuery(_c1, 5);
|
|
344
|
-
} if (rf & 2) {
|
|
345
|
-
let _t;
|
|
346
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.videoElement = _t.first);
|
|
347
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.progressRing = _t.first);
|
|
348
|
-
} }, inputs: { text1: "text1", text2: "text2", backFunction: "backFunction" }, outputs: { closeRequested: "closeRequested" }, decls: 21, vars: 8, consts: [["videoElement", ""], ["progressRing", ""], ["color", "light", 1, "custom-content"], ["class", "countdown-overlay", 4, "ngIf"], [1, "ion-no-border"], ["color", "light"], ["slot", "end"], [3, "click", "disabled"], ["name", "close", "color", "dark"], [1, "camera-container"], [1, "video-wrapper"], ["muted", "", "autoplay", "", "playsinline", "", 2, "transform", "scaleX(-1)"], ["width", "300", "height", "300", 1, "progress-ring"], ["cx", "150", "cy", "150", "r", "150", 1, "progress-ring__circle"], [3, "ngClass"], [1, "text-center"], [1, "fixed-footer"], ["class", "button-grabar", "expand", "block", 3, "click", 4, "ngIf"], ["expand", "block", 3, "disabled", "click", 4, "ngIf"], [1, "countdown-overlay"], [1, "countdown"], ["expand", "block", 1, "button-grabar", 3, "click"], ["expand", "block", 3, "click", "disabled"]], template: function CamaraVideoSelfieComponent_Template(rf, ctx) { if (rf & 1) {
|
|
349
|
-
const _r1 = i0.ɵɵgetCurrentView();
|
|
350
|
-
i0.ɵɵelementStart(0, "ion-content", 2);
|
|
351
|
-
i0.ɵɵtemplate(1, CamaraVideoSelfieComponent_div_1_Template, 3, 1, "div", 3);
|
|
352
|
-
i0.ɵɵelementStart(2, "ion-header", 4)(3, "ion-toolbar", 5)(4, "ion-buttons", 6)(5, "ion-button", 7);
|
|
353
|
-
i0.ɵɵlistener("click", function CamaraVideoSelfieComponent_Template_ion_button_click_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.closeOverlayVideo()); });
|
|
354
|
-
i0.ɵɵelement(6, "ion-icon", 8);
|
|
355
|
-
i0.ɵɵelementEnd()()()();
|
|
356
|
-
i0.ɵɵelementStart(7, "div", 9)(8, "div", 10);
|
|
357
|
-
i0.ɵɵelement(9, "video", 11, 0);
|
|
358
|
-
i0.ɵɵnamespaceSVG();
|
|
359
|
-
i0.ɵɵelementStart(11, "svg", 12, 1);
|
|
360
|
-
i0.ɵɵelement(13, "circle", 13);
|
|
361
|
-
i0.ɵɵelementEnd()();
|
|
362
|
-
i0.ɵɵnamespaceHTML();
|
|
363
|
-
i0.ɵɵelementStart(14, "ion-label", 14);
|
|
364
|
-
i0.ɵɵtext(15);
|
|
365
|
-
i0.ɵɵelementEnd();
|
|
366
|
-
i0.ɵɵelementStart(16, "p", 15);
|
|
367
|
-
i0.ɵɵtext(17, "Permanece quieto, con tu rostro en el centro del c\u00EDrculo.");
|
|
368
|
-
i0.ɵɵelementEnd();
|
|
369
|
-
i0.ɵɵelementStart(18, "div", 16);
|
|
370
|
-
i0.ɵɵtemplate(19, CamaraVideoSelfieComponent_ion_button_19_Template, 2, 0, "ion-button", 17)(20, CamaraVideoSelfieComponent_ion_button_20_Template, 2, 1, "ion-button", 18);
|
|
371
|
-
i0.ɵɵelementEnd()()();
|
|
372
|
-
} if (rf & 2) {
|
|
373
|
-
i0.ɵɵadvance();
|
|
374
|
-
i0.ɵɵproperty("ngIf", ctx.countdown > 0);
|
|
375
|
-
i0.ɵɵadvance(4);
|
|
376
|
-
i0.ɵɵproperty("disabled", !ctx.canStopRecording);
|
|
377
|
-
i0.ɵɵadvance(9);
|
|
378
|
-
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(6, _c2, ctx.isRecording));
|
|
379
|
-
i0.ɵɵadvance();
|
|
380
|
-
i0.ɵɵtextInterpolate1("00:", ctx.timeRemaining < 10 ? "0" + ctx.timeRemaining : ctx.timeRemaining, "");
|
|
381
|
-
i0.ɵɵadvance(4);
|
|
382
|
-
i0.ɵɵproperty("ngIf", !ctx.isRecording);
|
|
383
|
-
i0.ɵɵadvance();
|
|
384
|
-
i0.ɵɵproperty("ngIf", ctx.isRecording);
|
|
385
|
-
} }, dependencies: [i5.NgClass, i5.NgIf, i1.IonButton, i1.IonButtons, i1.IonContent, i1.IonHeader, i1.IonIcon, i1.IonLabel, i1.IonToolbar], styles: [".camera-container[_ngcontent-%COMP%] {\r\n justify-content: center;\r\n align-items: center;\r\n position: relative;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n height: 70%;\r\n background-color: #fff;\r\n}\r\n\r\n.video-wrapper[_ngcontent-%COMP%] {\r\n position: relative;\r\n width: 300px;\r\n height: 300px;\r\n border-radius: 50%;\r\n overflow: hidden;\r\n}\r\n\r\nvideo[_ngcontent-%COMP%] {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n border-radius: 50%;\r\n}\r\n\r\n.progress-ring[_ngcontent-%COMP%] {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n transform: rotate(-90deg);\r\n \n\r\n}\r\n\r\n.progress-ring__circle[_ngcontent-%COMP%] {\r\n fill: transparent;\r\n stroke: purple;\r\n stroke-width: 12;\r\n stroke-dasharray: 945;\r\n \n\r\n stroke-dashoffset: 880;\r\n \n\r\n transition: stroke-dashoffset 12s linear;\r\n \n\r\n}\r\n\r\n.progress-active[_ngcontent-%COMP%] .progress-ring__circle[_ngcontent-%COMP%] {\r\n animation: _ngcontent-%COMP%_progress-animation 5s linear forwards;\r\n}\r\n\r\n@keyframes _ngcontent-%COMP%_progress-animation {\r\n from {\r\n stroke-dashoffset: 880;\r\n }\r\n\r\n to {\r\n stroke-dashoffset: 0;\r\n }\r\n}\r\n\r\n.text-container[_ngcontent-%COMP%] {\r\n height: 40px;\r\n color: black;\r\n}\r\n\r\nion-header[_ngcontent-%COMP%] {\r\n --background: #fff;\r\n \n\r\n}\r\n\r\n.centered-title[_ngcontent-%COMP%] {\r\n text-align: center;\r\n width: 100%;\r\n \n\r\n font-weight: bold;\r\n}\r\n\r\n.fixed-footer[_ngcontent-%COMP%] {\r\n position: fixed;\r\n bottom: 40px;\r\n left: 0;\r\n width: 100%;\r\n padding: 10px;\r\n background-color: #fff; // Color de fondo, opcional\r\n // box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);\r\n\r\n\r\n ion-button {\r\n width: 90%;\r\n max-width: 300px;\r\n margin: 0 auto;\r\n color: #fff;\r\n font-weight: bold;\r\n border-radius: 20px;\r\n\r\n --background: #82298F;\r\n --background-hover: #82298F;\r\n --background-activated: #82298F;\r\n --background-focused: #82298F;\r\n\r\n --color: #fff;\r\n\r\n --border-radius: 20px;\r\n --border-color: #82298F;\r\n ;\r\n --border-style: solid;\r\n --border-width: 1px;\r\n\r\n --box-shadow: 0 2px 6px 0 rgb(0, 0, 0, 0.25);\r\n\r\n --ripple-color: #82298F;\r\n\r\n\r\n &:hover {\r\n background-color: #82298F;\r\n }\r\n\r\n &:active {\r\n background-color: #82298F;\r\n }\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n\r\nion-header[_ngcontent-%COMP%] {\r\n --background: #fff;\r\n \n\r\n color: #000000;\r\n \n\r\n}\r\n\r\nion-toolbar[_ngcontent-%COMP%] {\r\n --ion-background-color: #fff !important;\r\n --background: #ffffff !important;\r\n --color: #000000 !important;\r\n}\r\n\r\n.centered-title[_ngcontent-%COMP%] {\r\n flex: 1;\r\n text-align: center;\r\n \n\r\n font-weight: bold;\r\n color: #000000;\r\n margin: 0;\r\n \n\r\n}\r\n\r\nion-buttons[_ngcontent-%COMP%] {\r\n justify-content: flex-end;\r\n \n\r\n}\r\n\r\n.countdown-overlay[_ngcontent-%COMP%] {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background-color: rgba(0, 0, 0, 0.6);\r\n \n\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n margin: 0;\r\n padding: 0;\r\n z-index: 1000;\r\n \n\r\n animation: _ngcontent-%COMP%_fadeIn 0.5s ease-out, _ngcontent-%COMP%_fadeOut 0.5s ease-out 2.5s;\r\n \n\r\n box-sizing: border-box;\r\n border-radius: 0px;\r\n\r\n}\r\n\r\nion-content.custom-content[_ngcontent-%COMP%] {\r\n --padding-top: 0;\r\n --padding-bottom: 0;\r\n margin: 0;\r\n padding: 0;\r\n margin-top: 10vh; // Levanta el contenido un 10% desde el tope\r\n height: 90vh; // Ajusta la altura para que junto con el margin sea 100%\r\n}\r\n\r\n.countdown[_ngcontent-%COMP%] {\r\n font-size: 100px;\r\n font-weight: bold;\r\n color: #fff;\r\n animation: _ngcontent-%COMP%_scaleUp 0.5s ease-out, _ngcontent-%COMP%_scaleDown 0.5s ease-out 2.5s;\r\n \n\r\n}\r\n\r\n\n\r\n@keyframes _ngcontent-%COMP%_fadeIn {\r\n from {\r\n opacity: 0;\r\n }\r\n\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@keyframes _ngcontent-%COMP%_fadeOut {\r\n from {\r\n opacity: 1;\r\n }\r\n\r\n to {\r\n opacity: 0;\r\n }\r\n}\r\n\r\n\n\r\n@keyframes _ngcontent-%COMP%_scaleUp {\r\n from {\r\n transform: scale(0.8);\r\n opacity: 0;\r\n }\r\n\r\n to {\r\n transform: scale(1);\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@keyframes _ngcontent-%COMP%_scaleDown {\r\n from {\r\n transform: scale(1);\r\n opacity: 1;\r\n }\r\n\r\n to {\r\n transform: scale(0.8);\r\n opacity: 0;\r\n }\r\n}\r\n\r\n.red[_ngcontent-%COMP%] {\r\n padding: 10px;\r\n color: red;\r\n}\r\n\r\n.text-center[_ngcontent-%COMP%] {\r\n text-align: center;\r\n padding-left: 20%;\r\n padding-right: 20%;\r\n color: #333;\r\n}\r\n\r\n.loading-overlay[_ngcontent-%COMP%] {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background-color: rgba(0, 0, 0, 0.8);\r\n \n\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 1000;\r\n \n\r\n margin: 0;\r\n padding: 0;\r\n box-sizing: border-box;\r\n border-radius: 0px;\r\n}\r\n\r\nion-spinner[_ngcontent-%COMP%] {\r\n color: #fff;\r\n width: 50px;\r\n height: 50px;\r\n}"] }); }
|
|
386
|
-
}
|
|
387
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CamaraVideoSelfieComponent, [{
|
|
388
|
-
type: Component,
|
|
389
|
-
args: [{ selector: 'app-camara-video-selfie', encapsulation: ViewEncapsulation.Emulated, template: "<ion-content color=\"light\" class=\"custom-content\">\r\n <!-- Loading deshabilitado para evitar conflictos con loading principal -->\r\n <!-- <div *ngIf=\"isLoading\" class=\"loading-overlay\">\r\n <ion-spinner name=\"crescent\"></ion-spinner>\r\n </div> --> \r\n <div *ngIf=\"countdown > 0\" class=\"countdown-overlay\">\r\n <div class=\"countdown\">{{ countdown }}</div>\r\n </div>\r\n <ion-header class=\"ion-no-border\">\r\n <ion-toolbar color=\"light\">\r\n <!-- <ion-title class=\"centered-title\">Video Selfie</ion-title> -->\r\n <ion-buttons slot=\"end\">\r\n <ion-button (click)=\"closeOverlayVideo()\" [disabled]=\"!canStopRecording\">\r\n <ion-icon name=\"close\" color=\"dark\"></ion-icon>\r\n </ion-button>\r\n </ion-buttons>\r\n </ion-toolbar>\r\n </ion-header>\r\n <!-- Contenedor de la c\u00E1mara y progresi\u00F3n -->\r\n <div class=\"camera-container\">\r\n <div class=\"video-wrapper\">\r\n <video #videoElement muted autoplay playsinline style=\"transform: scaleX(-1)\"></video>\r\n <svg class=\"progress-ring\" #progressRing width=\"300\" height=\"300\">\r\n <circle class=\"progress-ring__circle\" cx=\"150\" cy=\"150\" r=\"150\" />\r\n </svg>\r\n </div>\r\n <ion-label [ngClass]=\"{'red': isRecording}\">00:{{ timeRemaining < 10 ? '0' + timeRemaining : timeRemaining\r\n }}</ion-label>\r\n <p class=\"text-center\">Permanece quieto, con tu rostro en el centro del c\u00EDrculo.</p>\r\n <!-- Botones de grabaci\u00F3n -->\r\n <div class=\"fixed-footer\">\r\n <ion-button class=\"button-grabar\" *ngIf=\"!isRecording\" expand=\"block\" (click)=\"recordVideo()\">Iniciar Grabaci\u00F3n</ion-button>\r\n <ion-button *ngIf=\"isRecording\" expand=\"block\" (click)=\"stopRecording()\" [disabled]=\"!canStopRecording\">Detener\r\n Grabaci\u00F3n</ion-button>\r\n </div>\r\n </div>\r\n</ion-content>", styles: [".camera-container {\r\n justify-content: center;\r\n align-items: center;\r\n position: relative;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n height: 70%;\r\n background-color: #fff;\r\n}\r\n\r\n.video-wrapper {\r\n position: relative;\r\n width: 300px;\r\n height: 300px;\r\n border-radius: 50%;\r\n overflow: hidden;\r\n}\r\n\r\nvideo {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n border-radius: 50%;\r\n}\r\n\r\n.progress-ring {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n transform: rotate(-90deg);\r\n /* Rotamos el c\u00EDrculo para que la animaci\u00F3n inicie desde arriba */\r\n}\r\n\r\n.progress-ring__circle {\r\n fill: transparent;\r\n stroke: purple;\r\n stroke-width: 12;\r\n stroke-dasharray: 945;\r\n /* La circunferencia del c\u00EDrculo 880*/\r\n stroke-dashoffset: 880;\r\n /* Oculto por completo al inicio */\r\n transition: stroke-dashoffset 12s linear;\r\n /* Esto controlar\u00E1 el llenado progresivo */\r\n}\r\n\r\n.progress-active .progress-ring__circle {\r\n animation: progress-animation 5s linear forwards;\r\n}\r\n\r\n@keyframes progress-animation {\r\n from {\r\n stroke-dashoffset: 880;\r\n }\r\n\r\n to {\r\n stroke-dashoffset: 0;\r\n }\r\n}\r\n\r\n.text-container {\r\n height: 40px;\r\n color: black;\r\n}\r\n\r\nion-header {\r\n --background: #fff;\r\n /* Fondo blanco para el header */\r\n}\r\n\r\n.centered-title {\r\n text-align: center;\r\n width: 100%;\r\n /* Asegura que el t\u00EDtulo est\u00E9 centrado */\r\n font-weight: bold;\r\n}\r\n\r\n.fixed-footer {\r\n position: fixed;\r\n bottom: 40px;\r\n left: 0;\r\n width: 100%;\r\n padding: 10px;\r\n background-color: #fff; // Color de fondo, opcional\r\n // box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);\r\n\r\n\r\n ion-button {\r\n width: 90%;\r\n max-width: 300px;\r\n margin: 0 auto;\r\n color: #fff;\r\n font-weight: bold;\r\n border-radius: 20px;\r\n\r\n --background: #82298F;\r\n --background-hover: #82298F;\r\n --background-activated: #82298F;\r\n --background-focused: #82298F;\r\n\r\n --color: #fff;\r\n\r\n --border-radius: 20px;\r\n --border-color: #82298F;\r\n ;\r\n --border-style: solid;\r\n --border-width: 1px;\r\n\r\n --box-shadow: 0 2px 6px 0 rgb(0, 0, 0, 0.25);\r\n\r\n --ripple-color: #82298F;\r\n\r\n\r\n &:hover {\r\n background-color: #82298F;\r\n }\r\n\r\n &:active {\r\n background-color: #82298F;\r\n }\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n\r\nion-header {\r\n --background: #fff;\r\n /* Fondo blanco */\r\n color: #000000;\r\n /* Texto negro */\r\n}\r\n\r\nion-toolbar {\r\n --ion-background-color: #fff !important;\r\n --background: #ffffff !important;\r\n --color: #000000 !important;\r\n}\r\n\r\n.centered-title {\r\n flex: 1;\r\n text-align: center;\r\n /* Centrar el t\u00EDtulo */\r\n font-weight: bold;\r\n color: #000000;\r\n margin: 0;\r\n /* Quita cualquier margen del t\u00EDtulo */\r\n}\r\n\r\nion-buttons {\r\n justify-content: flex-end;\r\n /* Alinea el bot\u00F3n a la derecha */\r\n}\r\n\r\n.countdown-overlay {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background-color: rgba(0, 0, 0, 0.6);\r\n /* Fondo semi-transparente */\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n margin: 0;\r\n padding: 0;\r\n z-index: 1000;\r\n /* Asegurarse de que est\u00E9 encima de otros elementos */\r\n animation: fadeIn 0.5s ease-out, fadeOut 0.5s ease-out 2.5s;\r\n /* Animaciones de entrada y salida */\r\n box-sizing: border-box;\r\n border-radius: 0px;\r\n\r\n}\r\n\r\nion-content.custom-content {\r\n --padding-top: 0;\r\n --padding-bottom: 0;\r\n margin: 0;\r\n padding: 0;\r\n margin-top: 10vh; // Levanta el contenido un 10% desde el tope\r\n height: 90vh; // Ajusta la altura para que junto con el margin sea 100%\r\n}\r\n\r\n.countdown {\r\n font-size: 100px;\r\n font-weight: bold;\r\n color: #fff;\r\n animation: scaleUp 0.5s ease-out, scaleDown 0.5s ease-out 2.5s;\r\n /* Escalar en entrada y salida */\r\n}\r\n\r\n/* Animaci\u00F3n para desvanecer la superposici\u00F3n */\r\n@keyframes fadeIn {\r\n from {\r\n opacity: 0;\r\n }\r\n\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@keyframes fadeOut {\r\n from {\r\n opacity: 1;\r\n }\r\n\r\n to {\r\n opacity: 0;\r\n }\r\n}\r\n\r\n/* Animaci\u00F3n para escalar el n\u00FAmero */\r\n@keyframes scaleUp {\r\n from {\r\n transform: scale(0.8);\r\n opacity: 0;\r\n }\r\n\r\n to {\r\n transform: scale(1);\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@keyframes scaleDown {\r\n from {\r\n transform: scale(1);\r\n opacity: 1;\r\n }\r\n\r\n to {\r\n transform: scale(0.8);\r\n opacity: 0;\r\n }\r\n}\r\n\r\n.red {\r\n padding: 10px;\r\n color: red;\r\n}\r\n\r\n.text-center {\r\n text-align: center;\r\n padding-left: 20%;\r\n padding-right: 20%;\r\n color: #333;\r\n}\r\n\r\n.loading-overlay {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background-color: rgba(0, 0, 0, 0.8);\r\n /* Fondo oscuro semi-transparente */\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 1000;\r\n /* Aseg\u00FArate de que est\u00E9 por encima del contenido */\r\n margin: 0;\r\n padding: 0;\r\n box-sizing: border-box;\r\n border-radius: 0px;\r\n}\r\n\r\nion-spinner {\r\n color: #fff;\r\n width: 50px;\r\n height: 50px;\r\n}"] }]
|
|
390
|
-
}], () => [{ type: i1.Platform }, { type: i1.ModalController }, { type: i2.DomSanitizer }, { type: i0.Renderer2 }, { type: i1.AlertController }, { type: i0.ChangeDetectorRef }, { type: i3.ModalVideoSelfieServices }, { type: i4.ModalDpiServices }], { videoElement: [{
|
|
391
|
-
type: ViewChild,
|
|
392
|
-
args: ['videoElement']
|
|
393
|
-
}], progressRing: [{
|
|
394
|
-
type: ViewChild,
|
|
395
|
-
args: ['progressRing']
|
|
396
|
-
}], text1: [{
|
|
397
|
-
type: Input
|
|
398
|
-
}], text2: [{
|
|
399
|
-
type: Input
|
|
400
|
-
}], backFunction: [{
|
|
401
|
-
type: Input
|
|
402
|
-
}], closeRequested: [{
|
|
403
|
-
type: Output
|
|
404
|
-
}] }); })();
|
|
405
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CamaraVideoSelfieComponent, { className: "CamaraVideoSelfieComponent", filePath: "src\\app\\pages\\id-vision\\components\\camara-video-selfie\\camara-video-selfie.component.ts", lineNumber: 20 }); })();
|
|
1
|
+
import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core';
|
|
2
|
+
import { Camera } from '@capacitor/camera';
|
|
3
|
+
import { ScreenBrightness } from '@capacitor-community/screen-brightness';
|
|
4
|
+
import { Capacitor } from '@capacitor/core';
|
|
5
|
+
import { App } from '@capacitor/app';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "@ionic/angular";
|
|
8
|
+
import * as i2 from "@angular/platform-browser";
|
|
9
|
+
import * as i3 from "../../services/modal-services/modal-video-selfie-services";
|
|
10
|
+
import * as i4 from "../../services/modal-services/modal-dpi-services";
|
|
11
|
+
import * as i5 from "@angular/common";
|
|
12
|
+
const _c0 = ["videoElement"];
|
|
13
|
+
const _c1 = ["progressRing"];
|
|
14
|
+
const _c2 = a0 => ({ "red": a0 });
|
|
15
|
+
function CamaraVideoSelfieComponent_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
16
|
+
i0.ɵɵelementStart(0, "div", 19)(1, "div", 20);
|
|
17
|
+
i0.ɵɵtext(2);
|
|
18
|
+
i0.ɵɵelementEnd()();
|
|
19
|
+
} if (rf & 2) {
|
|
20
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
21
|
+
i0.ɵɵadvance(2);
|
|
22
|
+
i0.ɵɵtextInterpolate(ctx_r1.countdown);
|
|
23
|
+
} }
|
|
24
|
+
function CamaraVideoSelfieComponent_ion_button_19_Template(rf, ctx) { if (rf & 1) {
|
|
25
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
26
|
+
i0.ɵɵelementStart(0, "ion-button", 21);
|
|
27
|
+
i0.ɵɵlistener("click", function CamaraVideoSelfieComponent_ion_button_19_Template_ion_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.recordVideo()); });
|
|
28
|
+
i0.ɵɵtext(1, "Iniciar Grabaci\u00F3n");
|
|
29
|
+
i0.ɵɵelementEnd();
|
|
30
|
+
} }
|
|
31
|
+
function CamaraVideoSelfieComponent_ion_button_20_Template(rf, ctx) { if (rf & 1) {
|
|
32
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
33
|
+
i0.ɵɵelementStart(0, "ion-button", 22);
|
|
34
|
+
i0.ɵɵlistener("click", function CamaraVideoSelfieComponent_ion_button_20_Template_ion_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.stopRecording()); });
|
|
35
|
+
i0.ɵɵtext(1, "Detener Grabaci\u00F3n");
|
|
36
|
+
i0.ɵɵelementEnd();
|
|
37
|
+
} if (rf & 2) {
|
|
38
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
39
|
+
i0.ɵɵproperty("disabled", !ctx_r1.canStopRecording);
|
|
40
|
+
} }
|
|
41
|
+
export class CamaraVideoSelfieComponent {
|
|
42
|
+
constructor(platform, modalController, sanitizer, renderer, alertController, changeDetector, modalVideoSelfieServices, modalDpiServices) {
|
|
43
|
+
this.platform = platform;
|
|
44
|
+
this.modalController = modalController;
|
|
45
|
+
this.sanitizer = sanitizer;
|
|
46
|
+
this.renderer = renderer;
|
|
47
|
+
this.alertController = alertController;
|
|
48
|
+
this.changeDetector = changeDetector;
|
|
49
|
+
this.modalVideoSelfieServices = modalVideoSelfieServices;
|
|
50
|
+
this.modalDpiServices = modalDpiServices;
|
|
51
|
+
this.text1 = '';
|
|
52
|
+
this.text2 = '';
|
|
53
|
+
this.closeRequested = new EventEmitter();
|
|
54
|
+
this.stream = null;
|
|
55
|
+
this.isRecording = false;
|
|
56
|
+
this.mediaRecorder = null;
|
|
57
|
+
this.recordedChunks = [];
|
|
58
|
+
this.countdown = 0;
|
|
59
|
+
this.minRecordingTime = 3000;
|
|
60
|
+
this.maxRecordingTime = 5000;
|
|
61
|
+
this.timeRemaining = this.maxRecordingTime / 1000;
|
|
62
|
+
this.canStopRecording = true;
|
|
63
|
+
this.isLoading = true;
|
|
64
|
+
this.defaultBrightness = null;
|
|
65
|
+
this.isAndroid = this.platform.is('android');
|
|
66
|
+
this.isIOS = this.platform.is('ios');
|
|
67
|
+
}
|
|
68
|
+
async ngAfterViewInit() {
|
|
69
|
+
if (this.isAndroid || this.isIOS) {
|
|
70
|
+
try {
|
|
71
|
+
const { brightness } = await ScreenBrightness.getBrightness();
|
|
72
|
+
this.defaultBrightness = brightness;
|
|
73
|
+
await ScreenBrightness.setBrightness({ brightness: 1.0 });
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.warn('Brillo error:', error);
|
|
77
|
+
}
|
|
78
|
+
await this.requestPermissions();
|
|
79
|
+
// 🔹 Listener para detectar cuando la app va a segundo plano
|
|
80
|
+
this.appStateListener = await App.addListener('appStateChange', async (state) => {
|
|
81
|
+
console.log('🔄 [VideoSelfie] App state changed:', state.isActive);
|
|
82
|
+
if (!state.isActive) {
|
|
83
|
+
console.log('⏸️ [VideoSelfie] App fue a background, cancelando grabación...');
|
|
84
|
+
await this.handleAppBackground();
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
console.log('✅ [VideoSelfie] App volvió al foreground, reiniciando cámara...');
|
|
88
|
+
await this.handleAppForeground();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
await this.initCamera();
|
|
93
|
+
await this.waitForCameraReady();
|
|
94
|
+
this.modalDpiServices.closeModalAndChangeBrightness$.subscribe(async () => await this.closeOverlayVideo());
|
|
95
|
+
}
|
|
96
|
+
async ngOnDestroy() {
|
|
97
|
+
if (this.appStateListener) {
|
|
98
|
+
await this.appStateListener.remove();
|
|
99
|
+
}
|
|
100
|
+
this.cleanupTimers();
|
|
101
|
+
this.stopCamera();
|
|
102
|
+
if (this.defaultBrightness !== null) {
|
|
103
|
+
await ScreenBrightness.setBrightness({ brightness: this.defaultBrightness });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async handleAppBackground() {
|
|
107
|
+
// Si está grabando o en countdown, cancelar todo
|
|
108
|
+
if (this.isRecording || this.countdown > 0) {
|
|
109
|
+
console.log('⚠️ [VideoSelfie] Grabación/Countdown en progreso, cancelando...');
|
|
110
|
+
await this.cancelRecording();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async handleAppForeground() {
|
|
114
|
+
// Reiniciar la cámara completamente
|
|
115
|
+
console.log('🔄 [VideoSelfie] Reiniciando cámara...');
|
|
116
|
+
this.isLoading = true;
|
|
117
|
+
this.changeDetector.detectChanges();
|
|
118
|
+
// Detener la cámara actual si existe
|
|
119
|
+
this.stopCamera();
|
|
120
|
+
// Reiniciar
|
|
121
|
+
await this.initCamera();
|
|
122
|
+
await this.waitForCameraReady();
|
|
123
|
+
this.isLoading = false;
|
|
124
|
+
this.changeDetector.detectChanges();
|
|
125
|
+
console.log('✅ [VideoSelfie] Cámara reiniciada, lista para grabar');
|
|
126
|
+
}
|
|
127
|
+
async cancelRecording() {
|
|
128
|
+
console.log('🚫 [VideoSelfie] Cancelando grabación...');
|
|
129
|
+
// Limpiar countdown
|
|
130
|
+
if (this.countdownInterval) {
|
|
131
|
+
clearInterval(this.countdownInterval);
|
|
132
|
+
this.countdownInterval = null;
|
|
133
|
+
}
|
|
134
|
+
this.countdown = 0;
|
|
135
|
+
// Detener grabación si está activa
|
|
136
|
+
if (this.mediaRecorder && this.isRecording) {
|
|
137
|
+
if (this.mediaRecorder.state !== 'inactive') {
|
|
138
|
+
this.mediaRecorder.stop();
|
|
139
|
+
}
|
|
140
|
+
this.isRecording = false;
|
|
141
|
+
}
|
|
142
|
+
// Limpiar timer de grabación
|
|
143
|
+
if (this.recordingTimer) {
|
|
144
|
+
clearTimeout(this.recordingTimer);
|
|
145
|
+
this.recordingTimer = null;
|
|
146
|
+
}
|
|
147
|
+
// Limpiar chunks grabados (no enviar video incompleto)
|
|
148
|
+
this.recordedChunks = [];
|
|
149
|
+
// Remover clase de progreso
|
|
150
|
+
if (this.progressRing) {
|
|
151
|
+
this.renderer.removeClass(this.progressRing.nativeElement, 'progress-active');
|
|
152
|
+
}
|
|
153
|
+
this.canStopRecording = true;
|
|
154
|
+
this.timeRemaining = this.maxRecordingTime / 1000;
|
|
155
|
+
this.changeDetector.detectChanges();
|
|
156
|
+
console.log('✅ [VideoSelfie] Grabación cancelada, no se enviará video');
|
|
157
|
+
}
|
|
158
|
+
cleanupTimers() {
|
|
159
|
+
if (this.recordingTimer) {
|
|
160
|
+
clearTimeout(this.recordingTimer);
|
|
161
|
+
this.recordingTimer = null;
|
|
162
|
+
}
|
|
163
|
+
if (this.countdownInterval) {
|
|
164
|
+
clearInterval(this.countdownInterval);
|
|
165
|
+
this.countdownInterval = null;
|
|
166
|
+
}
|
|
167
|
+
if (this.scanTimeout) {
|
|
168
|
+
clearTimeout(this.scanTimeout);
|
|
169
|
+
this.scanTimeout = null;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async requestPermissions() {
|
|
173
|
+
if (Capacitor.getPlatform() !== 'web') {
|
|
174
|
+
if (this.isAndroid || this.isIOS) {
|
|
175
|
+
const permissions = await Camera.requestPermissions();
|
|
176
|
+
if (permissions.camera === 'denied') {
|
|
177
|
+
console.error('Permiso de cámara denegado');
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async initCamera() {
|
|
184
|
+
try {
|
|
185
|
+
const constraints = {
|
|
186
|
+
audio: false,
|
|
187
|
+
video: {
|
|
188
|
+
facingMode: 'user',
|
|
189
|
+
width: { ideal: 640 }, // Fuerza resolución estándar
|
|
190
|
+
height: { ideal: 480 },
|
|
191
|
+
aspectRatio: 4 / 3
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
this.stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
195
|
+
const video = this.videoElement.nativeElement;
|
|
196
|
+
video.srcObject = this.stream;
|
|
197
|
+
video.setAttribute('playsinline', 'true');
|
|
198
|
+
video.muted = true;
|
|
199
|
+
// ⏳ Esperar un poco antes de reproducir para evitar salto de lente
|
|
200
|
+
await new Promise((res) => setTimeout(res, 300));
|
|
201
|
+
await video.play();
|
|
202
|
+
this.isLoading = false;
|
|
203
|
+
await this.prepareRecorder();
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
console.error('initCamera error:', error);
|
|
207
|
+
this.isLoading = false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
async waitForCameraReady() {
|
|
211
|
+
const video = this.videoElement.nativeElement;
|
|
212
|
+
return new Promise((resolve) => {
|
|
213
|
+
if (video.readyState >= 3) {
|
|
214
|
+
resolve();
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
video.onloadedmetadata = () => resolve();
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
async prepareRecorder() {
|
|
222
|
+
if (!this.stream || !this.stream.getVideoTracks().length)
|
|
223
|
+
return;
|
|
224
|
+
let mimeType = '';
|
|
225
|
+
if (this.isIOS && MediaRecorder.isTypeSupported('video/mp4')) {
|
|
226
|
+
mimeType = 'video/mp4';
|
|
227
|
+
}
|
|
228
|
+
else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
|
|
229
|
+
mimeType = 'video/webm;codecs=vp8';
|
|
230
|
+
}
|
|
231
|
+
else if (MediaRecorder.isTypeSupported('video/webm')) {
|
|
232
|
+
mimeType = 'video/webm';
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
alert('Formato no soportado');
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const options = {
|
|
239
|
+
mimeType,
|
|
240
|
+
videoBitsPerSecond: 400_000,
|
|
241
|
+
};
|
|
242
|
+
this.mediaRecorder = new MediaRecorder(this.stream, options);
|
|
243
|
+
this.recordedChunks = [];
|
|
244
|
+
this.mediaRecorder.ondataavailable = (event) => {
|
|
245
|
+
if (event.data?.size > 0)
|
|
246
|
+
this.recordedChunks.push(event.data);
|
|
247
|
+
};
|
|
248
|
+
this.mediaRecorder.onerror = (event) => {
|
|
249
|
+
console.error('Recorder error:', event);
|
|
250
|
+
alert('Error grabando video');
|
|
251
|
+
};
|
|
252
|
+
this.mediaRecorder.onstop = async () => {
|
|
253
|
+
if (!this.recordedChunks.length)
|
|
254
|
+
return;
|
|
255
|
+
const fileExtension = mimeType.includes('webm') ? 'webm' : 'mp4';
|
|
256
|
+
const blob = new Blob(this.recordedChunks, { type: mimeType });
|
|
257
|
+
const file = this.blobToFile(blob, `video-selfie.${fileExtension}`);
|
|
258
|
+
this.capVideo = file;
|
|
259
|
+
if (this.backFunction)
|
|
260
|
+
await this.backFunction(file);
|
|
261
|
+
this.recordedChunks = [];
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
recordVideo() {
|
|
265
|
+
this.countdown = 3;
|
|
266
|
+
this.countdownInterval = setInterval(() => {
|
|
267
|
+
this.countdown -= 1;
|
|
268
|
+
if (this.countdown <= 0) {
|
|
269
|
+
clearInterval(this.countdownInterval);
|
|
270
|
+
this.countdownInterval = null;
|
|
271
|
+
this.startVideoRecord();
|
|
272
|
+
}
|
|
273
|
+
this.changeDetector.detectChanges();
|
|
274
|
+
}, 1000);
|
|
275
|
+
}
|
|
276
|
+
async startVideoRecord() {
|
|
277
|
+
if (this.mediaRecorder && !this.isRecording) {
|
|
278
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
279
|
+
this.mediaRecorder.start();
|
|
280
|
+
this.isRecording = true;
|
|
281
|
+
this.canStopRecording = false;
|
|
282
|
+
this.renderer.addClass(this.progressRing.nativeElement, 'progress-active');
|
|
283
|
+
this.timeRemaining = this.maxRecordingTime / 1000;
|
|
284
|
+
this.updateTimeRemaining();
|
|
285
|
+
this.recordingTimer = setTimeout(async () => {
|
|
286
|
+
this.canStopRecording = true;
|
|
287
|
+
await this.stopRecording();
|
|
288
|
+
}, this.maxRecordingTime);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
updateTimeRemaining() {
|
|
292
|
+
const timer = setInterval(() => {
|
|
293
|
+
if (this.isRecording) {
|
|
294
|
+
this.timeRemaining -= 1;
|
|
295
|
+
if (this.timeRemaining <= 0)
|
|
296
|
+
clearInterval(timer);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
clearInterval(timer);
|
|
300
|
+
}
|
|
301
|
+
this.changeDetector.detectChanges();
|
|
302
|
+
}, 1000);
|
|
303
|
+
}
|
|
304
|
+
async stopRecording() {
|
|
305
|
+
if (this.mediaRecorder && this.isRecording && this.canStopRecording) {
|
|
306
|
+
if (this.mediaRecorder.state !== 'inactive')
|
|
307
|
+
this.mediaRecorder.stop();
|
|
308
|
+
this.isRecording = false;
|
|
309
|
+
}
|
|
310
|
+
if (this.scanTimeout)
|
|
311
|
+
clearTimeout(this.scanTimeout);
|
|
312
|
+
this.renderer.removeClass(this.progressRing.nativeElement, 'progress-active');
|
|
313
|
+
}
|
|
314
|
+
blobToFile(blob, fileName) {
|
|
315
|
+
const b = blob;
|
|
316
|
+
b.lastModified = Date.now();
|
|
317
|
+
b.lastModifiedDate = new Date();
|
|
318
|
+
b.name = fileName;
|
|
319
|
+
return b;
|
|
320
|
+
}
|
|
321
|
+
async closeOverlayVideo() {
|
|
322
|
+
this.stopCamera();
|
|
323
|
+
if (this.defaultBrightness !== null) {
|
|
324
|
+
await ScreenBrightness.setBrightness({ brightness: this.defaultBrightness });
|
|
325
|
+
}
|
|
326
|
+
this.modalController.dismiss();
|
|
327
|
+
}
|
|
328
|
+
stopCamera() {
|
|
329
|
+
if (this.stream) {
|
|
330
|
+
this.stream.getTracks().forEach((track) => track.stop());
|
|
331
|
+
this.stream = null;
|
|
332
|
+
}
|
|
333
|
+
if (this.scanTimeout)
|
|
334
|
+
clearTimeout(this.scanTimeout);
|
|
335
|
+
}
|
|
336
|
+
closeRequestedFunction() {
|
|
337
|
+
this.closeOverlayVideo();
|
|
338
|
+
this.modalDpiServices.requestCloseModalAndBrightness();
|
|
339
|
+
}
|
|
340
|
+
static { this.ɵfac = function CamaraVideoSelfieComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CamaraVideoSelfieComponent)(i0.ɵɵdirectiveInject(i1.Platform), i0.ɵɵdirectiveInject(i1.ModalController), i0.ɵɵdirectiveInject(i2.DomSanitizer), i0.ɵɵdirectiveInject(i0.Renderer2), i0.ɵɵdirectiveInject(i1.AlertController), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i3.ModalVideoSelfieServices), i0.ɵɵdirectiveInject(i4.ModalDpiServices)); }; }
|
|
341
|
+
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CamaraVideoSelfieComponent, selectors: [["app-camara-video-selfie"]], viewQuery: function CamaraVideoSelfieComponent_Query(rf, ctx) { if (rf & 1) {
|
|
342
|
+
i0.ɵɵviewQuery(_c0, 5);
|
|
343
|
+
i0.ɵɵviewQuery(_c1, 5);
|
|
344
|
+
} if (rf & 2) {
|
|
345
|
+
let _t;
|
|
346
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.videoElement = _t.first);
|
|
347
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.progressRing = _t.first);
|
|
348
|
+
} }, inputs: { text1: "text1", text2: "text2", backFunction: "backFunction" }, outputs: { closeRequested: "closeRequested" }, decls: 21, vars: 8, consts: [["videoElement", ""], ["progressRing", ""], ["color", "light", 1, "custom-content"], ["class", "countdown-overlay", 4, "ngIf"], [1, "ion-no-border"], ["color", "light"], ["slot", "end"], [3, "click", "disabled"], ["name", "close", "color", "dark"], [1, "camera-container"], [1, "video-wrapper"], ["muted", "", "autoplay", "", "playsinline", "", 2, "transform", "scaleX(-1)"], ["width", "300", "height", "300", 1, "progress-ring"], ["cx", "150", "cy", "150", "r", "150", 1, "progress-ring__circle"], [3, "ngClass"], [1, "text-center"], [1, "fixed-footer"], ["class", "button-grabar", "expand", "block", 3, "click", 4, "ngIf"], ["expand", "block", 3, "disabled", "click", 4, "ngIf"], [1, "countdown-overlay"], [1, "countdown"], ["expand", "block", 1, "button-grabar", 3, "click"], ["expand", "block", 3, "click", "disabled"]], template: function CamaraVideoSelfieComponent_Template(rf, ctx) { if (rf & 1) {
|
|
349
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
350
|
+
i0.ɵɵelementStart(0, "ion-content", 2);
|
|
351
|
+
i0.ɵɵtemplate(1, CamaraVideoSelfieComponent_div_1_Template, 3, 1, "div", 3);
|
|
352
|
+
i0.ɵɵelementStart(2, "ion-header", 4)(3, "ion-toolbar", 5)(4, "ion-buttons", 6)(5, "ion-button", 7);
|
|
353
|
+
i0.ɵɵlistener("click", function CamaraVideoSelfieComponent_Template_ion_button_click_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.closeOverlayVideo()); });
|
|
354
|
+
i0.ɵɵelement(6, "ion-icon", 8);
|
|
355
|
+
i0.ɵɵelementEnd()()()();
|
|
356
|
+
i0.ɵɵelementStart(7, "div", 9)(8, "div", 10);
|
|
357
|
+
i0.ɵɵelement(9, "video", 11, 0);
|
|
358
|
+
i0.ɵɵnamespaceSVG();
|
|
359
|
+
i0.ɵɵelementStart(11, "svg", 12, 1);
|
|
360
|
+
i0.ɵɵelement(13, "circle", 13);
|
|
361
|
+
i0.ɵɵelementEnd()();
|
|
362
|
+
i0.ɵɵnamespaceHTML();
|
|
363
|
+
i0.ɵɵelementStart(14, "ion-label", 14);
|
|
364
|
+
i0.ɵɵtext(15);
|
|
365
|
+
i0.ɵɵelementEnd();
|
|
366
|
+
i0.ɵɵelementStart(16, "p", 15);
|
|
367
|
+
i0.ɵɵtext(17, "Permanece quieto, con tu rostro en el centro del c\u00EDrculo.");
|
|
368
|
+
i0.ɵɵelementEnd();
|
|
369
|
+
i0.ɵɵelementStart(18, "div", 16);
|
|
370
|
+
i0.ɵɵtemplate(19, CamaraVideoSelfieComponent_ion_button_19_Template, 2, 0, "ion-button", 17)(20, CamaraVideoSelfieComponent_ion_button_20_Template, 2, 1, "ion-button", 18);
|
|
371
|
+
i0.ɵɵelementEnd()()();
|
|
372
|
+
} if (rf & 2) {
|
|
373
|
+
i0.ɵɵadvance();
|
|
374
|
+
i0.ɵɵproperty("ngIf", ctx.countdown > 0);
|
|
375
|
+
i0.ɵɵadvance(4);
|
|
376
|
+
i0.ɵɵproperty("disabled", !ctx.canStopRecording);
|
|
377
|
+
i0.ɵɵadvance(9);
|
|
378
|
+
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(6, _c2, ctx.isRecording));
|
|
379
|
+
i0.ɵɵadvance();
|
|
380
|
+
i0.ɵɵtextInterpolate1("00:", ctx.timeRemaining < 10 ? "0" + ctx.timeRemaining : ctx.timeRemaining, "");
|
|
381
|
+
i0.ɵɵadvance(4);
|
|
382
|
+
i0.ɵɵproperty("ngIf", !ctx.isRecording);
|
|
383
|
+
i0.ɵɵadvance();
|
|
384
|
+
i0.ɵɵproperty("ngIf", ctx.isRecording);
|
|
385
|
+
} }, dependencies: [i5.NgClass, i5.NgIf, i1.IonButton, i1.IonButtons, i1.IonContent, i1.IonHeader, i1.IonIcon, i1.IonLabel, i1.IonToolbar], styles: [".camera-container[_ngcontent-%COMP%] {\r\n justify-content: center;\r\n align-items: center;\r\n position: relative;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n height: 70%;\r\n background-color: #fff;\r\n}\r\n\r\n.video-wrapper[_ngcontent-%COMP%] {\r\n position: relative;\r\n width: 300px;\r\n height: 300px;\r\n border-radius: 50%;\r\n overflow: hidden;\r\n}\r\n\r\nvideo[_ngcontent-%COMP%] {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n border-radius: 50%;\r\n}\r\n\r\n.progress-ring[_ngcontent-%COMP%] {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n transform: rotate(-90deg);\r\n \n\r\n}\r\n\r\n.progress-ring__circle[_ngcontent-%COMP%] {\r\n fill: transparent;\r\n stroke: purple;\r\n stroke-width: 12;\r\n stroke-dasharray: 945;\r\n \n\r\n stroke-dashoffset: 880;\r\n \n\r\n transition: stroke-dashoffset 12s linear;\r\n \n\r\n}\r\n\r\n.progress-active[_ngcontent-%COMP%] .progress-ring__circle[_ngcontent-%COMP%] {\r\n animation: _ngcontent-%COMP%_progress-animation 5s linear forwards;\r\n}\r\n\r\n@keyframes _ngcontent-%COMP%_progress-animation {\r\n from {\r\n stroke-dashoffset: 880;\r\n }\r\n\r\n to {\r\n stroke-dashoffset: 0;\r\n }\r\n}\r\n\r\n.text-container[_ngcontent-%COMP%] {\r\n height: 40px;\r\n color: black;\r\n}\r\n\r\nion-header[_ngcontent-%COMP%] {\r\n --background: #fff;\r\n \n\r\n}\r\n\r\n.centered-title[_ngcontent-%COMP%] {\r\n text-align: center;\r\n width: 100%;\r\n \n\r\n font-weight: bold;\r\n}\r\n\r\n.fixed-footer[_ngcontent-%COMP%] {\r\n position: fixed;\r\n bottom: 40px;\r\n left: 0;\r\n width: 100%;\r\n padding: 10px;\r\n background-color: #fff; // Color de fondo, opcional\r\n // box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);\r\n\r\n\r\n ion-button {\r\n width: 90%;\r\n max-width: 300px;\r\n margin: 0 auto;\r\n color: #fff;\r\n font-weight: bold;\r\n border-radius: 20px;\r\n\r\n --background: #82298F;\r\n --background-hover: #82298F;\r\n --background-activated: #82298F;\r\n --background-focused: #82298F;\r\n\r\n --color: #fff;\r\n\r\n --border-radius: 20px;\r\n --border-color: #82298F;\r\n ;\r\n --border-style: solid;\r\n --border-width: 1px;\r\n\r\n --box-shadow: 0 2px 6px 0 rgb(0, 0, 0, 0.25);\r\n\r\n --ripple-color: #82298F;\r\n\r\n\r\n &:hover {\r\n background-color: #82298F;\r\n }\r\n\r\n &:active {\r\n background-color: #82298F;\r\n }\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n\r\nion-header[_ngcontent-%COMP%] {\r\n --background: #fff;\r\n \n\r\n color: #000000;\r\n \n\r\n}\r\n\r\nion-toolbar[_ngcontent-%COMP%] {\r\n --ion-background-color: #fff !important;\r\n --background: #ffffff !important;\r\n --color: #000000 !important;\r\n}\r\n\r\n.centered-title[_ngcontent-%COMP%] {\r\n flex: 1;\r\n text-align: center;\r\n \n\r\n font-weight: bold;\r\n color: #000000;\r\n margin: 0;\r\n \n\r\n}\r\n\r\nion-buttons[_ngcontent-%COMP%] {\r\n justify-content: flex-end;\r\n \n\r\n}\r\n\r\n.countdown-overlay[_ngcontent-%COMP%] {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background-color: rgba(0, 0, 0, 0.6);\r\n \n\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n margin: 0;\r\n padding: 0;\r\n z-index: 1000;\r\n \n\r\n animation: _ngcontent-%COMP%_fadeIn 0.5s ease-out, _ngcontent-%COMP%_fadeOut 0.5s ease-out 2.5s;\r\n \n\r\n box-sizing: border-box;\r\n border-radius: 0px;\r\n\r\n}\r\n\r\nion-content.custom-content[_ngcontent-%COMP%] {\r\n --padding-top: 0;\r\n --padding-bottom: 0;\r\n margin: 0;\r\n padding: 0;\r\n margin-top: 10vh; // Levanta el contenido un 10% desde el tope\r\n height: 90vh; // Ajusta la altura para que junto con el margin sea 100%\r\n}\r\n\r\n.countdown[_ngcontent-%COMP%] {\r\n font-size: 100px;\r\n font-weight: bold;\r\n color: #fff;\r\n animation: _ngcontent-%COMP%_scaleUp 0.5s ease-out, _ngcontent-%COMP%_scaleDown 0.5s ease-out 2.5s;\r\n \n\r\n}\r\n\r\n\n\r\n@keyframes _ngcontent-%COMP%_fadeIn {\r\n from {\r\n opacity: 0;\r\n }\r\n\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@keyframes _ngcontent-%COMP%_fadeOut {\r\n from {\r\n opacity: 1;\r\n }\r\n\r\n to {\r\n opacity: 0;\r\n }\r\n}\r\n\r\n\n\r\n@keyframes _ngcontent-%COMP%_scaleUp {\r\n from {\r\n transform: scale(0.8);\r\n opacity: 0;\r\n }\r\n\r\n to {\r\n transform: scale(1);\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@keyframes _ngcontent-%COMP%_scaleDown {\r\n from {\r\n transform: scale(1);\r\n opacity: 1;\r\n }\r\n\r\n to {\r\n transform: scale(0.8);\r\n opacity: 0;\r\n }\r\n}\r\n\r\n.red[_ngcontent-%COMP%] {\r\n padding: 10px;\r\n color: red;\r\n}\r\n\r\n.text-center[_ngcontent-%COMP%] {\r\n text-align: center;\r\n padding-left: 20%;\r\n padding-right: 20%;\r\n color: #333;\r\n}\r\n\r\n.loading-overlay[_ngcontent-%COMP%] {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background-color: rgba(0, 0, 0, 0.8);\r\n \n\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 1000;\r\n \n\r\n margin: 0;\r\n padding: 0;\r\n box-sizing: border-box;\r\n border-radius: 0px;\r\n}\r\n\r\nion-spinner[_ngcontent-%COMP%] {\r\n color: #fff;\r\n width: 50px;\r\n height: 50px;\r\n}"] }); }
|
|
386
|
+
}
|
|
387
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CamaraVideoSelfieComponent, [{
|
|
388
|
+
type: Component,
|
|
389
|
+
args: [{ selector: 'app-camara-video-selfie', encapsulation: ViewEncapsulation.Emulated, template: "<ion-content color=\"light\" class=\"custom-content\">\r\n <!-- Loading deshabilitado para evitar conflictos con loading principal -->\r\n <!-- <div *ngIf=\"isLoading\" class=\"loading-overlay\">\r\n <ion-spinner name=\"crescent\"></ion-spinner>\r\n </div> --> \r\n <div *ngIf=\"countdown > 0\" class=\"countdown-overlay\">\r\n <div class=\"countdown\">{{ countdown }}</div>\r\n </div>\r\n <ion-header class=\"ion-no-border\">\r\n <ion-toolbar color=\"light\">\r\n <!-- <ion-title class=\"centered-title\">Video Selfie</ion-title> -->\r\n <ion-buttons slot=\"end\">\r\n <ion-button (click)=\"closeOverlayVideo()\" [disabled]=\"!canStopRecording\">\r\n <ion-icon name=\"close\" color=\"dark\"></ion-icon>\r\n </ion-button>\r\n </ion-buttons>\r\n </ion-toolbar>\r\n </ion-header>\r\n <!-- Contenedor de la c\u00E1mara y progresi\u00F3n -->\r\n <div class=\"camera-container\">\r\n <div class=\"video-wrapper\">\r\n <video #videoElement muted autoplay playsinline style=\"transform: scaleX(-1)\"></video>\r\n <svg class=\"progress-ring\" #progressRing width=\"300\" height=\"300\">\r\n <circle class=\"progress-ring__circle\" cx=\"150\" cy=\"150\" r=\"150\" />\r\n </svg>\r\n </div>\r\n <ion-label [ngClass]=\"{'red': isRecording}\">00:{{ timeRemaining < 10 ? '0' + timeRemaining : timeRemaining\r\n }}</ion-label>\r\n <p class=\"text-center\">Permanece quieto, con tu rostro en el centro del c\u00EDrculo.</p>\r\n <!-- Botones de grabaci\u00F3n -->\r\n <div class=\"fixed-footer\">\r\n <ion-button class=\"button-grabar\" *ngIf=\"!isRecording\" expand=\"block\" (click)=\"recordVideo()\">Iniciar Grabaci\u00F3n</ion-button>\r\n <ion-button *ngIf=\"isRecording\" expand=\"block\" (click)=\"stopRecording()\" [disabled]=\"!canStopRecording\">Detener\r\n Grabaci\u00F3n</ion-button>\r\n </div>\r\n </div>\r\n</ion-content>", styles: [".camera-container {\r\n justify-content: center;\r\n align-items: center;\r\n position: relative;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n height: 70%;\r\n background-color: #fff;\r\n}\r\n\r\n.video-wrapper {\r\n position: relative;\r\n width: 300px;\r\n height: 300px;\r\n border-radius: 50%;\r\n overflow: hidden;\r\n}\r\n\r\nvideo {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n border-radius: 50%;\r\n}\r\n\r\n.progress-ring {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n transform: rotate(-90deg);\r\n /* Rotamos el c\u00EDrculo para que la animaci\u00F3n inicie desde arriba */\r\n}\r\n\r\n.progress-ring__circle {\r\n fill: transparent;\r\n stroke: purple;\r\n stroke-width: 12;\r\n stroke-dasharray: 945;\r\n /* La circunferencia del c\u00EDrculo 880*/\r\n stroke-dashoffset: 880;\r\n /* Oculto por completo al inicio */\r\n transition: stroke-dashoffset 12s linear;\r\n /* Esto controlar\u00E1 el llenado progresivo */\r\n}\r\n\r\n.progress-active .progress-ring__circle {\r\n animation: progress-animation 5s linear forwards;\r\n}\r\n\r\n@keyframes progress-animation {\r\n from {\r\n stroke-dashoffset: 880;\r\n }\r\n\r\n to {\r\n stroke-dashoffset: 0;\r\n }\r\n}\r\n\r\n.text-container {\r\n height: 40px;\r\n color: black;\r\n}\r\n\r\nion-header {\r\n --background: #fff;\r\n /* Fondo blanco para el header */\r\n}\r\n\r\n.centered-title {\r\n text-align: center;\r\n width: 100%;\r\n /* Asegura que el t\u00EDtulo est\u00E9 centrado */\r\n font-weight: bold;\r\n}\r\n\r\n.fixed-footer {\r\n position: fixed;\r\n bottom: 40px;\r\n left: 0;\r\n width: 100%;\r\n padding: 10px;\r\n background-color: #fff; // Color de fondo, opcional\r\n // box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);\r\n\r\n\r\n ion-button {\r\n width: 90%;\r\n max-width: 300px;\r\n margin: 0 auto;\r\n color: #fff;\r\n font-weight: bold;\r\n border-radius: 20px;\r\n\r\n --background: #82298F;\r\n --background-hover: #82298F;\r\n --background-activated: #82298F;\r\n --background-focused: #82298F;\r\n\r\n --color: #fff;\r\n\r\n --border-radius: 20px;\r\n --border-color: #82298F;\r\n ;\r\n --border-style: solid;\r\n --border-width: 1px;\r\n\r\n --box-shadow: 0 2px 6px 0 rgb(0, 0, 0, 0.25);\r\n\r\n --ripple-color: #82298F;\r\n\r\n\r\n &:hover {\r\n background-color: #82298F;\r\n }\r\n\r\n &:active {\r\n background-color: #82298F;\r\n }\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n\r\nion-header {\r\n --background: #fff;\r\n /* Fondo blanco */\r\n color: #000000;\r\n /* Texto negro */\r\n}\r\n\r\nion-toolbar {\r\n --ion-background-color: #fff !important;\r\n --background: #ffffff !important;\r\n --color: #000000 !important;\r\n}\r\n\r\n.centered-title {\r\n flex: 1;\r\n text-align: center;\r\n /* Centrar el t\u00EDtulo */\r\n font-weight: bold;\r\n color: #000000;\r\n margin: 0;\r\n /* Quita cualquier margen del t\u00EDtulo */\r\n}\r\n\r\nion-buttons {\r\n justify-content: flex-end;\r\n /* Alinea el bot\u00F3n a la derecha */\r\n}\r\n\r\n.countdown-overlay {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background-color: rgba(0, 0, 0, 0.6);\r\n /* Fondo semi-transparente */\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n margin: 0;\r\n padding: 0;\r\n z-index: 1000;\r\n /* Asegurarse de que est\u00E9 encima de otros elementos */\r\n animation: fadeIn 0.5s ease-out, fadeOut 0.5s ease-out 2.5s;\r\n /* Animaciones de entrada y salida */\r\n box-sizing: border-box;\r\n border-radius: 0px;\r\n\r\n}\r\n\r\nion-content.custom-content {\r\n --padding-top: 0;\r\n --padding-bottom: 0;\r\n margin: 0;\r\n padding: 0;\r\n margin-top: 10vh; // Levanta el contenido un 10% desde el tope\r\n height: 90vh; // Ajusta la altura para que junto con el margin sea 100%\r\n}\r\n\r\n.countdown {\r\n font-size: 100px;\r\n font-weight: bold;\r\n color: #fff;\r\n animation: scaleUp 0.5s ease-out, scaleDown 0.5s ease-out 2.5s;\r\n /* Escalar en entrada y salida */\r\n}\r\n\r\n/* Animaci\u00F3n para desvanecer la superposici\u00F3n */\r\n@keyframes fadeIn {\r\n from {\r\n opacity: 0;\r\n }\r\n\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@keyframes fadeOut {\r\n from {\r\n opacity: 1;\r\n }\r\n\r\n to {\r\n opacity: 0;\r\n }\r\n}\r\n\r\n/* Animaci\u00F3n para escalar el n\u00FAmero */\r\n@keyframes scaleUp {\r\n from {\r\n transform: scale(0.8);\r\n opacity: 0;\r\n }\r\n\r\n to {\r\n transform: scale(1);\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@keyframes scaleDown {\r\n from {\r\n transform: scale(1);\r\n opacity: 1;\r\n }\r\n\r\n to {\r\n transform: scale(0.8);\r\n opacity: 0;\r\n }\r\n}\r\n\r\n.red {\r\n padding: 10px;\r\n color: red;\r\n}\r\n\r\n.text-center {\r\n text-align: center;\r\n padding-left: 20%;\r\n padding-right: 20%;\r\n color: #333;\r\n}\r\n\r\n.loading-overlay {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background-color: rgba(0, 0, 0, 0.8);\r\n /* Fondo oscuro semi-transparente */\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 1000;\r\n /* Aseg\u00FArate de que est\u00E9 por encima del contenido */\r\n margin: 0;\r\n padding: 0;\r\n box-sizing: border-box;\r\n border-radius: 0px;\r\n}\r\n\r\nion-spinner {\r\n color: #fff;\r\n width: 50px;\r\n height: 50px;\r\n}"] }]
|
|
390
|
+
}], () => [{ type: i1.Platform }, { type: i1.ModalController }, { type: i2.DomSanitizer }, { type: i0.Renderer2 }, { type: i1.AlertController }, { type: i0.ChangeDetectorRef }, { type: i3.ModalVideoSelfieServices }, { type: i4.ModalDpiServices }], { videoElement: [{
|
|
391
|
+
type: ViewChild,
|
|
392
|
+
args: ['videoElement']
|
|
393
|
+
}], progressRing: [{
|
|
394
|
+
type: ViewChild,
|
|
395
|
+
args: ['progressRing']
|
|
396
|
+
}], text1: [{
|
|
397
|
+
type: Input
|
|
398
|
+
}], text2: [{
|
|
399
|
+
type: Input
|
|
400
|
+
}], backFunction: [{
|
|
401
|
+
type: Input
|
|
402
|
+
}], closeRequested: [{
|
|
403
|
+
type: Output
|
|
404
|
+
}] }); })();
|
|
405
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CamaraVideoSelfieComponent, { className: "CamaraVideoSelfieComponent", filePath: "src\\app\\pages\\id-vision\\components\\camara-video-selfie\\camara-video-selfie.component.ts", lineNumber: 20 }); })();
|
|
406
406
|
//# sourceMappingURL=camara-video-selfie.component.js.map
|