@dataclouder/ngx-cloud-storage 0.0.26 → 0.0.28

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.
@@ -1,17 +1,16 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Injectable, input, output, ViewChild, Component, ChangeDetectorRef, Input, signal, computed } from '@angular/core';
2
+ import { inject, Injectable, input, output, ViewChild, Component, Pipe, ChangeDetectorRef, Input, signal, computed } from '@angular/core';
3
3
  import { ImageCropperComponent } from 'ngx-image-cropper';
4
4
  import * as i1 from '@angular/forms';
5
5
  import { FormsModule } from '@angular/forms';
6
6
  import { AngularFireStorage } from '@angular/fire/compat/storage';
7
- import { getStorage, listAll, deleteObject, getDownloadURL, Storage, ref as ref$1 } from '@angular/fire/storage';
8
- import { ref, getStorage as getStorage$1, listAll as listAll$1, getDownloadURL as getDownloadURL$1 } from 'firebase/storage';
7
+ import { getStorage, ref, listAll, deleteObject, getDownloadURL, Storage } from '@angular/fire/storage';
9
8
  import { lastValueFrom, BehaviorSubject } from 'rxjs';
10
9
  import * as i4 from 'primeng/dialog';
11
10
  import { DialogModule } from 'primeng/dialog';
12
11
  import * as i5 from 'primeng/tooltip';
13
12
  import { TooltipModule } from 'primeng/tooltip';
14
- import * as i1$1 from 'primeng/button';
13
+ import * as i2 from 'primeng/button';
15
14
  import { ButtonModule } from 'primeng/button';
16
15
  import * as i6 from 'primeng/message';
17
16
  import { MessageModule } from 'primeng/message';
@@ -19,21 +18,190 @@ import * as i7 from 'primeng/select';
19
18
  import { SelectModule } from 'primeng/select';
20
19
  import * as i8 from 'primeng/inputtext';
21
20
  import { InputTextModule } from 'primeng/inputtext';
21
+ import { MoodStateOptions, CharacterEventActions } from '@dataclouder/ngx-core';
22
+ import * as i1$1 from '@angular/platform-browser';
22
23
  import * as i3 from 'primeng/api';
23
24
  import { AsyncPipe, CommonModule } from '@angular/common';
25
+ import * as i3$1 from 'primeng/tag';
26
+ import { TagModule } from 'primeng/tag';
24
27
 
25
28
  const AspectRatioOptions = [
26
- { value: '1:1', label: 'square', description: 'Square (1:1)', valueRatio: 1 / 1 },
27
- { value: '1:2', label: 'vertical_1_2', description: 'Vertical (1:2)', valueRatio: 1 / 2 },
28
- { value: '2:3', label: 'vertical_2_3', description: 'Vertical (2:3)', valueRatio: 2 / 3 },
29
- { value: '3:4', label: 'vertical_3_4', description: 'Vertical (3:4)', valueRatio: 3 / 4 },
30
- { value: '4:5', label: 'vertical_4_5', description: 'Vertical (4:5)', valueRatio: 4 / 5 },
31
- { value: '9:16', label: 'vertical_9_16', description: 'Vertical (9:16)', valueRatio: 9 / 16 },
32
- { value: '2:1', label: 'horizontal_2_1', description: 'Horizontal (2:1)', valueRatio: 2 / 1 },
33
- { value: '3:2', label: 'horizontal_3_2', description: 'Horizontal (3:2)', valueRatio: 3 / 2 },
34
- { value: '4:3', label: 'horizontal_4_3', description: 'Horizontal (4:3)', valueRatio: 4 / 3 },
35
- { value: '5:4', label: 'horizontal_5_4', description: 'Horizontal (5:4)', valueRatio: 5 / 4 },
36
- { value: '16:9', label: 'horizontal_16_9', description: 'Horizontal (16:9)', valueRatio: 16 / 9 },
29
+ {
30
+ value: '1:1',
31
+ label: 'square',
32
+ description: 'Square (1:1)',
33
+ valueRatio: 1 / 1,
34
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="4" width="16" height="16" rx="2" /></svg>`,
35
+ resolution: {
36
+ veryLow: { w: 240, h: 240 },
37
+ low: { w: 360, h: 360 },
38
+ sd: { w: 480, h: 480 },
39
+ sdLarge: { w: 540, h: 540 },
40
+ hd: { w: 720, h: 720 },
41
+ fullhd: { w: 1080, h: 1080 },
42
+ '4k': { w: 2160, h: 2160 },
43
+ },
44
+ },
45
+ {
46
+ value: '1:2',
47
+ label: 'vertical_1_2',
48
+ description: 'Vertical (1:2)',
49
+ valueRatio: 1 / 2,
50
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="7" y="4" width="9" height="18" rx="2" /></svg>`,
51
+ resolution: {
52
+ veryLow: { w: 240, h: 480 },
53
+ low: { w: 360, h: 720 },
54
+ sd: { w: 480, h: 960 },
55
+ sdLarge: { w: 540, h: 1080 },
56
+ hd: { w: 720, h: 1440 },
57
+ fullhd: { w: 1080, h: 2160 },
58
+ '4k': { w: 2160, h: 4320 },
59
+ },
60
+ },
61
+ {
62
+ value: '9:16',
63
+ label: 'vertical_9_16',
64
+ description: 'Vertical (9:16)',
65
+ valueRatio: 9 / 16,
66
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="7" y="4" width="9" height="16" rx="2" /></svg>`,
67
+ resolution: {
68
+ veryLow: { w: 240, h: 427 },
69
+ low: { w: 360, h: 640 },
70
+ sd: { w: 450, h: 800 },
71
+ sdLarge: { w: 540, h: 960 },
72
+ hd: { w: 720, h: 1280 },
73
+ fullhd: { w: 1080, h: 1920 },
74
+ '4k': { w: 2160, h: 3840 },
75
+ },
76
+ },
77
+ {
78
+ value: '2:3',
79
+ label: 'vertical_2_3',
80
+ description: 'Vertical (2:3)',
81
+ valueRatio: 2 / 3,
82
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="4" width="12" height="18" rx="2" /></svg>`,
83
+ resolution: {
84
+ veryLow: { w: 240, h: 360 },
85
+ low: { w: 360, h: 540 },
86
+ sd: { w: 480, h: 720 },
87
+ sdLarge: { w: 540, h: 810 },
88
+ hd: { w: 720, h: 1080 },
89
+ fullhd: { w: 1080, h: 1620 },
90
+ '4k': { w: 2160, h: 3240 },
91
+ },
92
+ },
93
+ {
94
+ value: '3:4',
95
+ label: 'vertical_3_4',
96
+ description: 'Vertical (3:4)',
97
+ valueRatio: 3 / 4,
98
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="4" width="12" height="16" rx="2" /></svg>`,
99
+ resolution: {
100
+ veryLow: { w: 240, h: 320 },
101
+ low: { w: 360, h: 480 },
102
+ sd: { w: 480, h: 640 },
103
+ sdLarge: { w: 540, h: 720 },
104
+ hd: { w: 720, h: 960 },
105
+ fullhd: { w: 1080, h: 1440 },
106
+ '4k': { w: 2160, h: 2880 },
107
+ },
108
+ },
109
+ {
110
+ value: '4:5',
111
+ label: 'vertical_4_5',
112
+ description: 'Vertical (4:5)',
113
+ valueRatio: 4 / 5,
114
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="4" width="12" height="15" rx="2" /></svg>`,
115
+ resolution: {
116
+ veryLow: { w: 240, h: 300 },
117
+ low: { w: 360, h: 450 },
118
+ sd: { w: 480, h: 600 },
119
+ sdLarge: { w: 540, h: 675 },
120
+ hd: { w: 720, h: 900 },
121
+ fullhd: { w: 1080, h: 1350 },
122
+ '4k': { w: 2160, h: 2700 },
123
+ },
124
+ },
125
+ {
126
+ value: '2:1',
127
+ label: 'horizontal_2_1',
128
+ description: 'Horizontal (2:1)',
129
+ valueRatio: 2 / 1,
130
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="8" width="18" height="9" rx="2" /></svg>`,
131
+ resolution: {
132
+ veryLow: { w: 480, h: 240 },
133
+ low: { w: 720, h: 360 },
134
+ sd: { w: 960, h: 480 },
135
+ sdLarge: { w: 1080, h: 540 },
136
+ hd: { w: 1440, h: 720 },
137
+ fullhd: { w: 2160, h: 1080 },
138
+ '4k': { w: 4320, h: 2160 },
139
+ },
140
+ },
141
+ {
142
+ value: '16:9',
143
+ label: 'horizontal_16_9',
144
+ description: 'Horizontal (16:9)',
145
+ valueRatio: 16 / 9,
146
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="7.5" width="18" height="10.125" rx="2" /></svg>`,
147
+ resolution: {
148
+ veryLow: { w: 240, h: 426 },
149
+ low: { w: 360, h: 640 },
150
+ sd: { w: 468, h: 832 },
151
+ sdLarge: { w: 540, h: 960 },
152
+ hd: { w: 720, h: 1280 },
153
+ fullhd: { w: 1080, h: 1920 },
154
+ '4k': { w: 2160, h: 3840 },
155
+ },
156
+ },
157
+ {
158
+ value: '3:2',
159
+ label: 'horizontal_3_2',
160
+ description: 'Horizontal (3:2)',
161
+ valueRatio: 3 / 2,
162
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="18" height="12" rx="2" /></svg>`,
163
+ resolution: {
164
+ veryLow: { w: 360, h: 240 },
165
+ low: { w: 540, h: 360 },
166
+ sd: { w: 720, h: 480 },
167
+ sdLarge: { w: 810, h: 540 },
168
+ hd: { w: 1080, h: 720 },
169
+ fullhd: { w: 1620, h: 1080 },
170
+ '4k': { w: 3240, h: 2160 },
171
+ },
172
+ },
173
+ {
174
+ value: '4:3',
175
+ label: 'horizontal_4_3',
176
+ description: 'Horizontal (4:3)',
177
+ valueRatio: 4 / 3,
178
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="6" width="16" height="12" rx="2" /></svg>`,
179
+ resolution: {
180
+ veryLow: { w: 320, h: 240 },
181
+ low: { w: 480, h: 360 },
182
+ sd: { w: 640, h: 480 },
183
+ sdLarge: { w: 720, h: 540 },
184
+ hd: { w: 960, h: 720 },
185
+ fullhd: { w: 1440, h: 1080 },
186
+ '4k': { w: 2880, h: 2160 },
187
+ },
188
+ },
189
+ {
190
+ value: '5:4',
191
+ label: 'horizontal_5_4',
192
+ description: 'Horizontal (5:4)',
193
+ valueRatio: 5 / 4,
194
+ icon: `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="5.6" width="16" height="12.8" rx="2" /></svg>`,
195
+ resolution: {
196
+ veryLow: { w: 300, h: 240 },
197
+ low: { w: 450, h: 360 },
198
+ sd: { w: 600, h: 480 },
199
+ sdLarge: { w: 675, h: 540 },
200
+ hd: { w: 900, h: 720 },
201
+ fullhd: { w: 1350, h: 1080 },
202
+ '4k': { w: 2700, h: 2160 },
203
+ },
204
+ },
37
205
  ];
38
206
  var AspectType;
39
207
  (function (AspectType) {
@@ -87,7 +255,7 @@ const FIREBASE_STORAGE_URL_REGEX = /https:\/\/firebasestorage\.googleapis\.com\/
87
255
  * The URL is expected to follow the pattern:
88
256
  * 'https://firebasestorage.googleapis.com/v0/b/&lt;bucket&gt;/&lt;path&gt;?&lt;query_params&gt;'
89
257
  *
90
- * @param data The CloudStorageData object containing the 'url' property.
258
+ * @param data The BasicStorage object containing the 'url' property.
91
259
  * @returns The bucket name (e.g., 'appingles-pro.appspot.com') or undefined if not found or URL is invalid.
92
260
  */
93
261
  function extractBucket(data) {
@@ -106,7 +274,7 @@ function extractBucket(data) {
106
274
  * 'https://firebasestorage.googleapis.com/v0/b/&lt;bucket&gt;/&lt;path&gt;?&lt;query_params&gt;'
107
275
  * The extracted path is the part after the bucket and before any query parameters.
108
276
  *
109
- * @param data The CloudStorageData object containing the 'url' property.
277
+ * @param data The BasicStorage object containing the 'url' property.
110
278
  * @returns The file path (e.g., 'scenarios/666506c3b9b5443f4bfab5e0/images/hairdresser.webp')
111
279
  * or undefined if not found or URL is invalid.
112
280
  * Note: This function does not perform URL decoding on the path. If URL-decoded paths
@@ -182,28 +350,12 @@ class MultiImagesStorageService {
182
350
  console.log('image deleted', res);
183
351
  });
184
352
  }
185
- async uploadAndGetUrl(task, resolution) {
186
- const snap = await task;
187
- const { fullPath, bucket, name, contentType, size } = snap.metadata;
188
- const storage = getStorage();
189
- const storageRef = ref(storage, fullPath);
190
- const url = await getDownloadURL(storageRef);
191
- const meta = {
192
- url,
193
- name,
194
- resolution,
195
- type: contentType,
196
- size,
197
- resolutions: {}, // Default empty resolutions
198
- };
199
- return meta;
200
- }
201
- async uploadGenericFile(file, storagePath) {
353
+ async uploadGenericFile(file, storagePath, metadata) {
202
354
  try {
203
355
  // Ensure storagePath is a directory path, and append file.name
204
- const fullFilePath = `${storagePath.replace(/\/$/, '')}/${file.name}`;
356
+ const fullFilePath = `${storagePath.replace(/\/$/, '')}/${Date.now()}-${file.name}`;
205
357
  const refStorage = this.storage.ref(fullFilePath);
206
- const task = await refStorage.put(file);
358
+ const task = await refStorage.put(file, { customMetadata: metadata });
207
359
  const url = await lastValueFrom(refStorage.getDownloadURL());
208
360
  const fileData = {
209
361
  url,
@@ -219,10 +371,10 @@ class MultiImagesStorageService {
219
371
  return null;
220
372
  }
221
373
  }
222
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: MultiImagesStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
223
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: MultiImagesStorageService, providedIn: 'root' }); }
374
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: MultiImagesStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
375
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: MultiImagesStorageService, providedIn: 'root' }); }
224
376
  }
225
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: MultiImagesStorageService, decorators: [{
377
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: MultiImagesStorageService, decorators: [{
226
378
  type: Injectable,
227
379
  args: [{
228
380
  providedIn: 'root',
@@ -233,9 +385,9 @@ class CropperComponent {
233
385
  constructor() {
234
386
  this.multiImagesStorageService = inject(MultiImagesStorageService);
235
387
  // overrides name, path and resizeToWidth
236
- this.imageSettings = input({});
237
- this.ratioType = input(AspectType.Square);
238
- this.resolutions = input([ResolutionType.MediumLarge]);
388
+ this.imageSettings = input({}, ...(ngDevMode ? [{ debugName: "imageSettings" }] : []));
389
+ this.ratioType = input(AspectType.Square, ...(ngDevMode ? [{ debugName: "ratioType" }] : []));
390
+ this.resolutions = input([ResolutionType.MediumLarge], ...(ngDevMode ? [{ debugName: "resolutions" }] : []));
239
391
  // Outputs
240
392
  this.imageUploaded = output();
241
393
  this.onImageCropped = output();
@@ -291,10 +443,10 @@ class CropperComponent {
291
443
  closeModal() {
292
444
  this.showModal = false;
293
445
  }
294
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CropperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
295
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: CropperComponent, isStandalone: true, selector: "app-cropper", inputs: { imageSettings: { classPropertyName: "imageSettings", publicName: "imageSettings", isSignal: true, isRequired: false, transformFunction: null }, ratioType: { classPropertyName: "ratioType", publicName: "ratioType", isSignal: true, isRequired: false, transformFunction: null }, resolutions: { classPropertyName: "resolutions", publicName: "resolutions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { imageUploaded: "imageUploaded", onImageCropped: "onImageCropped", onFileSelected: "onFileSelected" }, viewQueries: [{ propertyName: "imageCropper", first: true, predicate: ImageCropperComponent, descendants: true }], ngImport: i0, template: "<div> path: {{ storagePath }} </div>\n\n<div class=\"options\">\n @if (!isUploaded) {\n <div>\n <input type=\"file\" id=\"file-upload\" class=\"file-input\" (change)=\"fileChangeEvent($event)\" />\n <label for=\"file-upload\" class=\"btn-upload\">Seleccionar archivo</label>\n @if (!fileMetadata) {\n <em>Carga una imagen para comenzar</em>\n }\n </div>\n }\n\n @if (fileMetadata) {\n <span>\n <span style=\"margin: 1px 20px\"> tipo: {{ fileMetadata.type }} </span>\n <span style=\"margin: 1px 20px\"> tama\u00F1o {{ fileMetadata.size }} </span>\n <br />\n <input\n [disabled]=\"imageSettings()?.fileName\"\n style=\"margin: 1px 20px; width: 400px\"\n [(ngModel)]=\"renameFile\"\n type=\"text\"\n placeholder=\"Rename File\"\n (ngModelChange)=\"reloadPath()\" />\n <button class=\"btn-crop\" (click)=\"closeModal()\"> Recortar y Subir </button>\n </span>\n }\n</div>\n\n@if (fileMetadata && !isUploaded) {\n <div class=\"modal\" [class.show-modal]=\"showModal\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <h3>Recortar imagen</h3>\n <button class=\"close-button\" (click)=\"closeModal()\">\u00D7</button>\n </div>\n <div class=\"modal-body\">\n <h1>Hlloa</h1>\n <image-cropper\n [imageChangedEvent]=\"imageChangedEvent\"\n [maintainAspectRatio]=\"true\"\n [aspectRatio]=\"aspectRatio\"\n format=\"webp\"\n [resizeToWidth]=\"450\"\n (imageCropped)=\"onInnerImageCropped($event)\"\n (loadImageFailed)=\"loadImageFailed()\"\n (imageLoaded)=\"imageLoaded($event)\"\n [autoCrop]=\"false\"></image-cropper>\n <div class=\"modal-footer\">\n <button class=\"btn-crop\" (click)=\"simpleCropAndUpload()\">Recortar y Subir</button>\n </div>\n </div>\n </div>\n </div>\n}\n\n@if (croppedImage && !isUploaded) {\n <button [disabled]=\"isLoading\" nbButton status=\"info\"> upload </button>\n}\n", styles: [".options{display:flex}.btn-crop{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid transparent;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd;border-color:#0d6efd}.btn-crop :hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.file-input{display:none}.btn-upload{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid #0d6efd;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd}.btn-upload:hover{color:#fff;background-color:#0d6efd}.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;z-index:1000}.modal.show-modal{display:flex;align-items:center;justify-content:center}.modal .modal-content{background-color:#fff;border-radius:8px;width:90%;max-width:800px;max-height:90vh;overflow-y:auto;position:relative}.modal .modal-header{padding:1rem;border-bottom:1px solid #dee2e6;display:flex;justify-content:space-between;align-items:center}.modal .modal-header h3{margin:0}.modal .modal-header .close-button{background:none;border:none;font-size:1.5rem;cursor:pointer;padding:0;color:#6c757d}.modal .modal-header .close-button:hover{color:#343a40}.modal .modal-body{padding:1rem}.modal .modal-footer{padding:1rem;border-top:1px solid #dee2e6;display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "imageAltText", "options", "cropperFrameAriaLabel", "output", "format", "autoCrop", "cropper", "transform", "maintainAspectRatio", "aspectRatio", "resetCropOnAspectRatioChange", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "allowMoveImage", "checkImageType", "alignImage", "disabled", "hidden"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed", "transformChange", "cropperChange"] }] }); }
446
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CropperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
447
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: CropperComponent, isStandalone: true, selector: "app-cropper", inputs: { imageSettings: { classPropertyName: "imageSettings", publicName: "imageSettings", isSignal: true, isRequired: false, transformFunction: null }, ratioType: { classPropertyName: "ratioType", publicName: "ratioType", isSignal: true, isRequired: false, transformFunction: null }, resolutions: { classPropertyName: "resolutions", publicName: "resolutions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { imageUploaded: "imageUploaded", onImageCropped: "onImageCropped", onFileSelected: "onFileSelected" }, viewQueries: [{ propertyName: "imageCropper", first: true, predicate: ImageCropperComponent, descendants: true }], ngImport: i0, template: "<div> path: {{ storagePath }} </div>\n\n<div class=\"options\">\n @if (!isUploaded) {\n <div>\n <input type=\"file\" id=\"file-upload\" class=\"file-input\" (change)=\"fileChangeEvent($event)\" />\n <label for=\"file-upload\" class=\"btn-upload\">Seleccionar archivo</label>\n @if (!fileMetadata) {\n <em>Carga una imagen para comenzar</em>\n }\n </div>\n }\n\n @if (fileMetadata) {\n <span>\n <span style=\"margin: 1px 20px\"> tipo: {{ fileMetadata.type }} </span>\n <span style=\"margin: 1px 20px\"> tama\u00F1o {{ fileMetadata.size }} </span>\n <br />\n <input\n [disabled]=\"imageSettings()?.fileName\"\n style=\"margin: 1px 20px; width: 400px\"\n [(ngModel)]=\"renameFile\"\n type=\"text\"\n placeholder=\"Rename File\"\n (ngModelChange)=\"reloadPath()\" />\n <button class=\"btn-crop\" (click)=\"closeModal()\"> Recortar y Subir </button>\n </span>\n }\n</div>\n\n@if (fileMetadata && !isUploaded) {\n <div class=\"modal\" [class.show-modal]=\"showModal\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <h3>Recortar imagen</h3>\n <button class=\"close-button\" (click)=\"closeModal()\">\u00D7</button>\n </div>\n <div class=\"modal-body\">\n <h1>Hlloa</h1>\n <image-cropper\n [imageChangedEvent]=\"imageChangedEvent\"\n [maintainAspectRatio]=\"true\"\n [aspectRatio]=\"aspectRatio\"\n format=\"webp\"\n [resizeToWidth]=\"450\"\n (imageCropped)=\"onInnerImageCropped($event)\"\n (loadImageFailed)=\"loadImageFailed()\"\n (imageLoaded)=\"imageLoaded($event)\"\n [autoCrop]=\"false\"></image-cropper>\n <div class=\"modal-footer\">\n <button class=\"btn-crop\" (click)=\"simpleCropAndUpload()\">Recortar y Subir</button>\n </div>\n </div>\n </div>\n </div>\n}\n\n@if (croppedImage && !isUploaded) {\n <button [disabled]=\"isLoading\" nbButton status=\"info\"> upload </button>\n}\n", styles: [".options{display:flex}.btn-crop{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid transparent;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd;border-color:#0d6efd}.btn-crop :hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.file-input{display:none}.btn-upload{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid #0d6efd;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd}.btn-upload:hover{color:#fff;background-color:#0d6efd}.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;z-index:1000}.modal.show-modal{display:flex;align-items:center;justify-content:center}.modal .modal-content{background-color:#fff;border-radius:8px;width:90%;max-width:800px;max-height:90vh;overflow-y:auto;position:relative}.modal .modal-header{padding:1rem;border-bottom:1px solid #dee2e6;display:flex;justify-content:space-between;align-items:center}.modal .modal-header h3{margin:0}.modal .modal-header .close-button{background:none;border:none;font-size:1.5rem;cursor:pointer;padding:0;color:#6c757d}.modal .modal-header .close-button:hover{color:#343a40}.modal .modal-body{padding:1rem}.modal .modal-footer{padding:1rem;border-top:1px solid #dee2e6;display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "imageAltText", "options", "cropperFrameAriaLabel", "output", "format", "autoCrop", "cropper", "transform", "maintainAspectRatio", "aspectRatio", "resetCropOnAspectRatioChange", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "allowMoveImage", "checkImageType", "alignImage", "disabled", "hidden"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed", "transformChange", "cropperChange"] }] }); }
296
448
  }
297
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CropperComponent, decorators: [{
449
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CropperComponent, decorators: [{
298
450
  type: Component,
299
451
  args: [{ selector: 'app-cropper', standalone: true, imports: [FormsModule, ImageCropperComponent], template: "<div> path: {{ storagePath }} </div>\n\n<div class=\"options\">\n @if (!isUploaded) {\n <div>\n <input type=\"file\" id=\"file-upload\" class=\"file-input\" (change)=\"fileChangeEvent($event)\" />\n <label for=\"file-upload\" class=\"btn-upload\">Seleccionar archivo</label>\n @if (!fileMetadata) {\n <em>Carga una imagen para comenzar</em>\n }\n </div>\n }\n\n @if (fileMetadata) {\n <span>\n <span style=\"margin: 1px 20px\"> tipo: {{ fileMetadata.type }} </span>\n <span style=\"margin: 1px 20px\"> tama\u00F1o {{ fileMetadata.size }} </span>\n <br />\n <input\n [disabled]=\"imageSettings()?.fileName\"\n style=\"margin: 1px 20px; width: 400px\"\n [(ngModel)]=\"renameFile\"\n type=\"text\"\n placeholder=\"Rename File\"\n (ngModelChange)=\"reloadPath()\" />\n <button class=\"btn-crop\" (click)=\"closeModal()\"> Recortar y Subir </button>\n </span>\n }\n</div>\n\n@if (fileMetadata && !isUploaded) {\n <div class=\"modal\" [class.show-modal]=\"showModal\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <h3>Recortar imagen</h3>\n <button class=\"close-button\" (click)=\"closeModal()\">\u00D7</button>\n </div>\n <div class=\"modal-body\">\n <h1>Hlloa</h1>\n <image-cropper\n [imageChangedEvent]=\"imageChangedEvent\"\n [maintainAspectRatio]=\"true\"\n [aspectRatio]=\"aspectRatio\"\n format=\"webp\"\n [resizeToWidth]=\"450\"\n (imageCropped)=\"onInnerImageCropped($event)\"\n (loadImageFailed)=\"loadImageFailed()\"\n (imageLoaded)=\"imageLoaded($event)\"\n [autoCrop]=\"false\"></image-cropper>\n <div class=\"modal-footer\">\n <button class=\"btn-crop\" (click)=\"simpleCropAndUpload()\">Recortar y Subir</button>\n </div>\n </div>\n </div>\n </div>\n}\n\n@if (croppedImage && !isUploaded) {\n <button [disabled]=\"isLoading\" nbButton status=\"info\"> upload </button>\n}\n", styles: [".options{display:flex}.btn-crop{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid transparent;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd;border-color:#0d6efd}.btn-crop :hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.file-input{display:none}.btn-upload{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid #0d6efd;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd}.btn-upload:hover{color:#fff;background-color:#0d6efd}.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;z-index:1000}.modal.show-modal{display:flex;align-items:center;justify-content:center}.modal .modal-content{background-color:#fff;border-radius:8px;width:90%;max-width:800px;max-height:90vh;overflow-y:auto;position:relative}.modal .modal-header{padding:1rem;border-bottom:1px solid #dee2e6;display:flex;justify-content:space-between;align-items:center}.modal .modal-header h3{margin:0}.modal .modal-header .close-button{background:none;border:none;font-size:1.5rem;cursor:pointer;padding:0;color:#6c757d}.modal .modal-header .close-button:hover{color:#343a40}.modal .modal-body{padding:1rem}.modal .modal-footer{padding:1rem;border-top:1px solid #dee2e6;display:flex;justify-content:flex-end}\n"] }]
300
452
  }], propDecorators: { imageCropper: [{
@@ -302,18 +454,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
302
454
  args: [ImageCropperComponent]
303
455
  }] } });
304
456
 
457
+ class SafeHtmlPipe {
458
+ constructor(sanitizer) {
459
+ this.sanitizer = sanitizer;
460
+ }
461
+ transform(value) {
462
+ return this.sanitizer.bypassSecurityTrustHtml(value);
463
+ }
464
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SafeHtmlPipe, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe }); }
465
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: SafeHtmlPipe, isStandalone: true, name: "safeHtml" }); }
466
+ }
467
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SafeHtmlPipe, decorators: [{
468
+ type: Pipe,
469
+ args: [{
470
+ name: 'safeHtml',
471
+ standalone: true,
472
+ }]
473
+ }], ctorParameters: () => [{ type: i1$1.DomSanitizer }] });
474
+
305
475
  class CropperComponentModal {
306
476
  constructor() {
307
477
  this.multiImagesStorageService = inject(MultiImagesStorageService);
308
478
  this.changeDetectorRef = inject(ChangeDetectorRef);
309
479
  // overrides name, path and resizeToWidth
310
- this.imgStorageSettings = input(DEFAULT_SETTINGS);
311
- this.buttonLabel = input('Seleccionar archivo');
480
+ this.imgStorageSettings = input(DEFAULT_SETTINGS, ...(ngDevMode ? [{ debugName: "imgStorageSettings" }] : []));
481
+ this.buttonLabel = input('Seleccionar archivo', ...(ngDevMode ? [{ debugName: "buttonLabel" }] : []));
312
482
  this.currentStorage = {};
313
483
  this.imageUploaded = output();
314
484
  this.onImageCropped = output();
315
485
  this.onFileSelected = output();
316
486
  this.aspectRatioOptions = AspectRatioOptions;
487
+ this.MoodStateOptions = MoodStateOptions;
317
488
  this.fileMetadata = null;
318
489
  this.displayDialog = false;
319
490
  this.aspectRatioValue = 1;
@@ -322,6 +493,7 @@ class CropperComponentModal {
322
493
  this.storagePath = '';
323
494
  this.resizeToWidth = 450;
324
495
  this.ratioSelected = null;
496
+ this.emotionSelected = null;
325
497
  // Generate random ID for file input
326
498
  this.fileInputId = `file-upload-${Math.random().toString(36).substring(2, 11)}`;
327
499
  }
@@ -405,7 +577,7 @@ class CropperComponentModal {
405
577
  this.multiImagesStorageService.deleteImage(path);
406
578
  }
407
579
  console.log('imgStorage', imgStorage);
408
- this.imageUploaded.emit(imgStorage);
580
+ this.imageUploaded.emit({ ...imgStorage, metadata: this.emotionSelected });
409
581
  this.displayDialog = false;
410
582
  this.changeDetectorRef.detectChanges();
411
583
  }
@@ -415,12 +587,17 @@ class CropperComponentModal {
415
587
  this.aspectRatioValue = event.valueRatio;
416
588
  this.changeDetectorRef.detectChanges();
417
589
  }
418
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CropperComponentModal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
419
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: CropperComponentModal, isStandalone: true, selector: "dc-cropper-modal", inputs: { imgStorageSettings: { classPropertyName: "imgStorageSettings", publicName: "imgStorageSettings", isSignal: true, isRequired: false, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, currentStorage: { classPropertyName: "currentStorage", publicName: "currentStorage", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { imageUploaded: "imageUploaded", onImageCropped: "onImageCropped", onFileSelected: "onFileSelected" }, viewQueries: [{ propertyName: "imageCropper", first: true, predicate: ImageCropperComponent, descendants: true }], ngImport: i0, template: "<div class=\"upload-section\">\n <input type=\"file\" [id]=\"fileInputId\" class=\"file-input\" (change)=\"fileChangeEvent($event)\" />\n <label pButton [for]=\"fileInputId\" [pTooltip]=\"storagePath\" class=\"upload-button\">\n {{ buttonLabel() }}\n </label>\n</div>\n@if(displayDialog) {\n<!-- Cropper Dialog -->\n\n<p-dialog header=\"Recortar imagen\" [(visible)]=\"displayDialog\" [modal]=\"true\" [draggable]=\"false\" [resizable]=\"false\" styleClass=\"cropper-dialog\">\n <!-- Image Settings Section -->\n <div class=\"settings-section\">\n @if(!imgStorageSettings().path) {\n <p-message severity=\"warn\">Developer Note: make sure you have a path to save the image pass object imgStorageSettings</p-message>\n } @if(currentStorage?.url) {\n\n <p-message severity=\"warn\" variant=\"outlined\">\n <div>\n <span class=\"setting-label\">Image will be replaced:</span>\n <img width=\"100\" height=\"Auto\" [src]=\"currentStorage?.url\" />\n </div>\n </p-message>\n\n }\n\n <p-message>\n <b>Estas opciones estan preconfiguradas y no se pueden cambiar</b>\n\n <ul>\n <li> <b>Path to save:</b> {{ storagePath }}< </li>\n <li>\n <b>Resoluciones:</b>\n <span>{{ imgStorageSettings()?.cropSettings?.resolutions }}</span>\n </li>\n </ul>\n </p-message>\n\n <div class=\"setting-item\">\n <span class=\"setting-label\">Aspecto:</span>\n <p class=\"setting-value\">{{ imgStorageSettings()?.cropSettings?.aspectRatio }}</p>\n </div>\n\n <p-select\n [options]=\"aspectRatioOptions\"\n [ngModel]=\"ratioSelected\"\n (ngModelChange)=\"changeRatio($event)\"\n optionLabel=\"description\"\n placeholder=\"Select a ratio\" />\n\n <!-- File Metadata Section -->\n @if (fileMetadata) {\n <div class=\"metadata-section\">\n <span class=\"metadata-item\">tipo: {{ fileMetadata.type }}</span>\n <span class=\"metadata-item\">tama\u00F1o: {{ fileMetadata.size }}</span>\n </div>\n }\n\n <!-- Rename Input -->\n <input\n pInputText\n [disabled]=\"imgStorageSettings()?.fileName\"\n [(ngModel)]=\"renameFile\"\n type=\"text\"\n placeholder=\"Rename File\"\n (ngModelChange)=\"reloadPath()\"\n class=\"rename-input\" />\n </div>\n\n <!-- Image Cropper -->\n\n <div class=\"cropper-container-father\">\n <image-cropper\n [imageChangedEvent]=\"imageChangedEvent\"\n [maintainAspectRatio]=\"true\"\n [aspectRatio]=\"aspectRatioValue\"\n format=\"webp\"\n [resizeToWidth]=\"resizeToWidth\"\n (imageCropped)=\"onInnerImageCropped($event)\"\n (loadImageFailed)=\"loadImageFailed()\"\n (cropperReady)=\"cropperReady()\"\n [autoCrop]=\"false\">\n </image-cropper>\n </div>\n <!-- Dialog Footer -->\n <ng-template pTemplate=\"footer\">\n <div class=\"dialog-footer\">\n <button pButton class=\"p-button-primary\" (click)=\"simpleCropAndUpload()\"> Recortar y Subir </button>\n </div>\n </ng-template>\n</p-dialog>\n}\n", styles: [":host{display:block}:host ::ng-deep .ngx-ic-overlay{width:100%!important}.upload-section{margin-bottom:1rem}.upload-section .file-input{display:none}.upload-section .upload-button{cursor:pointer}::ng-deep .cropper-dialog{max-width:90vw;width:800px}::ng-deep .cropper-dialog .p-dialog-content{padding:1.5rem}.settings-section{margin-bottom:1.5rem}.settings-section .settings-header{color:var(--text-color-secondary);margin-bottom:1rem}.settings-section .settings-grid{display:grid;gap:1rem;margin-bottom:1.5rem}.settings-section .settings-grid .setting-item .setting-label{font-weight:600;color:var(--text-color);display:block;margin-bottom:.5rem}.settings-section .settings-grid .setting-item .setting-value{color:var(--text-color-secondary);margin:0}.metadata-section{display:flex;gap:1.5rem;margin-bottom:1rem}.metadata-section .metadata-item{color:var(--text-color-secondary)}.rename-section{margin-bottom:5px}.rename-section .rename-input{width:100%;padding:.5rem;border:1px solid var(--surface-border);border-radius:4px}.rename-section .rename-input:disabled{background-color:var(--surface-200);cursor:not-allowed}.cropper-container-father{display:flex;justify-content:center;align-items:center;height:65vh}.dialog-footer{display:flex;justify-content:flex-end;gap:1rem}.btn-crop{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid transparent;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd;border-color:#0d6efd}.btn-crop :hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.file-input{display:none}.btn-upload{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid #0d6efd;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd}.btn-upload:hover{color:#fff;background-color:#0d6efd}.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;z-index:1000}.modal.show-modal{display:flex;align-items:center;justify-content:center}.modal .modal-content{background-color:#fff;border-radius:8px;width:90%;max-width:800px;max-height:90vh;overflow-y:auto;position:relative}.modal .modal-header{padding:1rem;border-bottom:1px solid #dee2e6;display:flex;justify-content:space-between;align-items:center}.modal .modal-header h3{margin:0}.modal .modal-header .close-button{background:none;border:none;font-size:1.5rem;cursor:pointer;padding:0;color:#6c757d}.modal .modal-header .close-button:hover{color:#343a40}.modal .modal-body{padding:1rem;height:100vh;display:flex;flex-direction:column}.modal .modal-footer{padding:1rem;border-top:1px solid #dee2e6;display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "imageAltText", "options", "cropperFrameAriaLabel", "output", "format", "autoCrop", "cropper", "transform", "maintainAspectRatio", "aspectRatio", "resetCropOnAspectRatioChange", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "allowMoveImage", "checkImageType", "alignImage", "disabled", "hidden"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed", "transformChange", "cropperChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i1$1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i6.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i7.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }] }); }
590
+ addEmotion(event) {
591
+ // Will only log for now
592
+ console.log('addEmotion', event);
593
+ this.emotionSelected = event;
594
+ }
595
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CropperComponentModal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
596
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: CropperComponentModal, isStandalone: true, selector: "dc-cropper-modal", inputs: { imgStorageSettings: { classPropertyName: "imgStorageSettings", publicName: "imgStorageSettings", isSignal: true, isRequired: false, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, currentStorage: { classPropertyName: "currentStorage", publicName: "currentStorage", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { imageUploaded: "imageUploaded", onImageCropped: "onImageCropped", onFileSelected: "onFileSelected" }, viewQueries: [{ propertyName: "imageCropper", first: true, predicate: ImageCropperComponent, descendants: true }], ngImport: i0, template: "<div class=\"upload-section\">\n <input type=\"file\" [id]=\"fileInputId\" class=\"file-input\" (change)=\"fileChangeEvent($event)\" />\n <label pButton [for]=\"fileInputId\" [pTooltip]=\"storagePath\" class=\"upload-button\">\n {{ buttonLabel() }}\n </label>\n</div>\n@if(displayDialog) {\n<!-- Cropper Dialog -->\n\n<p-dialog header=\"Recortar imagen\" [(visible)]=\"displayDialog\" [modal]=\"true\" [draggable]=\"false\" [resizable]=\"false\" styleClass=\"cropper-dialog\">\n <!-- Image Settings Section -->\n <div class=\"settings-section\">\n @if(!imgStorageSettings().path) {\n <p-message severity=\"warn\">Developer Note: make sure you have a path to save the image pass object imgStorageSettings</p-message>\n } @if(currentStorage?.url) {\n\n <p-message severity=\"warn\" variant=\"outlined\">\n <div>\n <span class=\"setting-label\">Image will be replaced:</span>\n <img width=\"100\" height=\"Auto\" [src]=\"currentStorage?.url\" />\n </div>\n </p-message>\n\n }\n\n <p-message>\n <b>Estas opciones estan preconfiguradas y no se pueden cambiar</b>\n\n <ul>\n <li> <b>Path to save:</b> {{ storagePath }}< </li>\n <li>\n <b>Resoluciones:</b>\n <span>{{ imgStorageSettings()?.cropSettings?.resolutions }}</span>\n </li>\n </ul>\n </p-message>\n\n <div class=\"setting-item\">\n <span class=\"setting-label\">Aspecto:</span>\n <p class=\"setting-value\">{{ imgStorageSettings()?.cropSettings?.aspectRatio }}</p>\n </div>\n\n <p-select\n [options]=\"aspectRatioOptions\"\n [ngModel]=\"ratioSelected\"\n (ngModelChange)=\"changeRatio($event)\"\n optionLabel=\"description\"\n placeholder=\"Select a ratio\">\n <ng-template pTemplate=\"selectedItem\" let-selectedOption>\n @if(selectedOption) {\n <div class=\"flex items-center gap-2\">\n <div [innerHTML]=\"selectedOption.icon | safeHtml\"></div>\n <div>{{ selectedOption.description }}</div>\n </div>\n }\n </ng-template>\n <ng-template let-ratio pTemplate=\"item\">\n <div class=\"flex items-center gap-2\">\n <div [innerHTML]=\"ratio.icon | safeHtml\"></div>\n <div>{{ ratio.description }}</div>\n </div>\n </ng-template>\n </p-select>\n\n <!-- File Metadata Section -->\n @if (fileMetadata) {\n <div class=\"metadata-section\">\n <span class=\"metadata-item\">tipo: {{ fileMetadata.type }}</span>\n <span class=\"metadata-item\">tama\u00F1o: {{ fileMetadata.size }}</span>\n </div>\n }\n\n <!-- Rename Input -->\n <input\n pInputText\n [disabled]=\"imgStorageSettings()?.fileName\"\n [(ngModel)]=\"renameFile\"\n type=\"text\"\n placeholder=\"Rename File\"\n (ngModelChange)=\"reloadPath()\"\n class=\"rename-input\" />\n\n <h5>Datos adicionales</h5>\n\n <p-select\n [options]=\"MoodStateOptions\"\n [(ngModel)]=\"emotionSelected\"\n (ngModelChange)=\"addEmotion($event)\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select an emotion\" />\n </div>\n\n <!-- Image Cropper -->\n\n <div class=\"cropper-container-father\">\n <image-cropper\n [imageChangedEvent]=\"imageChangedEvent\"\n [maintainAspectRatio]=\"true\"\n [aspectRatio]=\"aspectRatioValue\"\n format=\"webp\"\n [resizeToWidth]=\"resizeToWidth\"\n (imageCropped)=\"onInnerImageCropped($event)\"\n (loadImageFailed)=\"loadImageFailed()\"\n (cropperReady)=\"cropperReady()\"\n [autoCrop]=\"false\">\n </image-cropper>\n </div>\n <!-- Dialog Footer -->\n <ng-template pTemplate=\"footer\">\n <div class=\"dialog-footer\">\n <button pButton class=\"p-button-primary\" (click)=\"simpleCropAndUpload()\"> Recortar y Subir </button>\n </div>\n </ng-template>\n</p-dialog>\n}\n", styles: [":host{display:block}:host ::ng-deep .ngx-ic-overlay{width:100%!important}.upload-section{margin-bottom:1rem}.upload-section .file-input{display:none}.upload-section .upload-button{cursor:pointer}::ng-deep .cropper-dialog{max-width:90vw;width:800px}::ng-deep .cropper-dialog .p-dialog-content{padding:1.5rem}.settings-section{margin-bottom:1.5rem}.settings-section .settings-header{color:var(--text-color-secondary);margin-bottom:1rem}.settings-section .settings-grid{display:grid;gap:1rem;margin-bottom:1.5rem}.settings-section .settings-grid .setting-item .setting-label{font-weight:600;color:var(--text-color);display:block;margin-bottom:.5rem}.settings-section .settings-grid .setting-item .setting-value{color:var(--text-color-secondary);margin:0}.metadata-section{display:flex;gap:1.5rem;margin-bottom:1rem}.metadata-section .metadata-item{color:var(--text-color-secondary)}.rename-section{margin-bottom:5px}.rename-section .rename-input{width:100%;padding:.5rem;border:1px solid var(--surface-border);border-radius:4px}.rename-section .rename-input:disabled{background-color:var(--surface-200);cursor:not-allowed}.cropper-container-father{display:flex;justify-content:center;align-items:center;height:65vh}.dialog-footer{display:flex;justify-content:flex-end;gap:1rem}.btn-crop{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid transparent;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd;border-color:#0d6efd}.btn-crop :hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.file-input{display:none}.btn-upload{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid #0d6efd;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd}.btn-upload:hover{color:#fff;background-color:#0d6efd}.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;z-index:1000}.modal.show-modal{display:flex;align-items:center;justify-content:center}.modal .modal-content{background-color:#fff;border-radius:8px;width:90%;max-width:800px;max-height:90vh;overflow-y:auto;position:relative}.modal .modal-header{padding:1rem;border-bottom:1px solid #dee2e6;display:flex;justify-content:space-between;align-items:center}.modal .modal-header h3{margin:0}.modal .modal-header .close-button{background:none;border:none;font-size:1.5rem;cursor:pointer;padding:0;color:#6c757d}.modal .modal-header .close-button:hover{color:#343a40}.modal .modal-body{padding:1rem;height:100vh;display:flex;flex-direction:column}.modal .modal-footer{padding:1rem;border-top:1px solid #dee2e6;display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "imageAltText", "options", "cropperFrameAriaLabel", "output", "format", "autoCrop", "cropper", "transform", "maintainAspectRatio", "aspectRatio", "resetCropOnAspectRatioChange", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "allowMoveImage", "checkImageType", "alignImage", "disabled", "hidden"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed", "transformChange", "cropperChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i6.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i7.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }] }); }
420
597
  }
421
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CropperComponentModal, decorators: [{
598
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CropperComponentModal, decorators: [{
422
599
  type: Component,
423
- args: [{ selector: 'dc-cropper-modal', standalone: true, imports: [FormsModule, ImageCropperComponent, ButtonModule, DialogModule, TooltipModule, MessageModule, SelectModule, InputTextModule], template: "<div class=\"upload-section\">\n <input type=\"file\" [id]=\"fileInputId\" class=\"file-input\" (change)=\"fileChangeEvent($event)\" />\n <label pButton [for]=\"fileInputId\" [pTooltip]=\"storagePath\" class=\"upload-button\">\n {{ buttonLabel() }}\n </label>\n</div>\n@if(displayDialog) {\n<!-- Cropper Dialog -->\n\n<p-dialog header=\"Recortar imagen\" [(visible)]=\"displayDialog\" [modal]=\"true\" [draggable]=\"false\" [resizable]=\"false\" styleClass=\"cropper-dialog\">\n <!-- Image Settings Section -->\n <div class=\"settings-section\">\n @if(!imgStorageSettings().path) {\n <p-message severity=\"warn\">Developer Note: make sure you have a path to save the image pass object imgStorageSettings</p-message>\n } @if(currentStorage?.url) {\n\n <p-message severity=\"warn\" variant=\"outlined\">\n <div>\n <span class=\"setting-label\">Image will be replaced:</span>\n <img width=\"100\" height=\"Auto\" [src]=\"currentStorage?.url\" />\n </div>\n </p-message>\n\n }\n\n <p-message>\n <b>Estas opciones estan preconfiguradas y no se pueden cambiar</b>\n\n <ul>\n <li> <b>Path to save:</b> {{ storagePath }}< </li>\n <li>\n <b>Resoluciones:</b>\n <span>{{ imgStorageSettings()?.cropSettings?.resolutions }}</span>\n </li>\n </ul>\n </p-message>\n\n <div class=\"setting-item\">\n <span class=\"setting-label\">Aspecto:</span>\n <p class=\"setting-value\">{{ imgStorageSettings()?.cropSettings?.aspectRatio }}</p>\n </div>\n\n <p-select\n [options]=\"aspectRatioOptions\"\n [ngModel]=\"ratioSelected\"\n (ngModelChange)=\"changeRatio($event)\"\n optionLabel=\"description\"\n placeholder=\"Select a ratio\" />\n\n <!-- File Metadata Section -->\n @if (fileMetadata) {\n <div class=\"metadata-section\">\n <span class=\"metadata-item\">tipo: {{ fileMetadata.type }}</span>\n <span class=\"metadata-item\">tama\u00F1o: {{ fileMetadata.size }}</span>\n </div>\n }\n\n <!-- Rename Input -->\n <input\n pInputText\n [disabled]=\"imgStorageSettings()?.fileName\"\n [(ngModel)]=\"renameFile\"\n type=\"text\"\n placeholder=\"Rename File\"\n (ngModelChange)=\"reloadPath()\"\n class=\"rename-input\" />\n </div>\n\n <!-- Image Cropper -->\n\n <div class=\"cropper-container-father\">\n <image-cropper\n [imageChangedEvent]=\"imageChangedEvent\"\n [maintainAspectRatio]=\"true\"\n [aspectRatio]=\"aspectRatioValue\"\n format=\"webp\"\n [resizeToWidth]=\"resizeToWidth\"\n (imageCropped)=\"onInnerImageCropped($event)\"\n (loadImageFailed)=\"loadImageFailed()\"\n (cropperReady)=\"cropperReady()\"\n [autoCrop]=\"false\">\n </image-cropper>\n </div>\n <!-- Dialog Footer -->\n <ng-template pTemplate=\"footer\">\n <div class=\"dialog-footer\">\n <button pButton class=\"p-button-primary\" (click)=\"simpleCropAndUpload()\"> Recortar y Subir </button>\n </div>\n </ng-template>\n</p-dialog>\n}\n", styles: [":host{display:block}:host ::ng-deep .ngx-ic-overlay{width:100%!important}.upload-section{margin-bottom:1rem}.upload-section .file-input{display:none}.upload-section .upload-button{cursor:pointer}::ng-deep .cropper-dialog{max-width:90vw;width:800px}::ng-deep .cropper-dialog .p-dialog-content{padding:1.5rem}.settings-section{margin-bottom:1.5rem}.settings-section .settings-header{color:var(--text-color-secondary);margin-bottom:1rem}.settings-section .settings-grid{display:grid;gap:1rem;margin-bottom:1.5rem}.settings-section .settings-grid .setting-item .setting-label{font-weight:600;color:var(--text-color);display:block;margin-bottom:.5rem}.settings-section .settings-grid .setting-item .setting-value{color:var(--text-color-secondary);margin:0}.metadata-section{display:flex;gap:1.5rem;margin-bottom:1rem}.metadata-section .metadata-item{color:var(--text-color-secondary)}.rename-section{margin-bottom:5px}.rename-section .rename-input{width:100%;padding:.5rem;border:1px solid var(--surface-border);border-radius:4px}.rename-section .rename-input:disabled{background-color:var(--surface-200);cursor:not-allowed}.cropper-container-father{display:flex;justify-content:center;align-items:center;height:65vh}.dialog-footer{display:flex;justify-content:flex-end;gap:1rem}.btn-crop{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid transparent;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd;border-color:#0d6efd}.btn-crop :hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.file-input{display:none}.btn-upload{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid #0d6efd;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd}.btn-upload:hover{color:#fff;background-color:#0d6efd}.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;z-index:1000}.modal.show-modal{display:flex;align-items:center;justify-content:center}.modal .modal-content{background-color:#fff;border-radius:8px;width:90%;max-width:800px;max-height:90vh;overflow-y:auto;position:relative}.modal .modal-header{padding:1rem;border-bottom:1px solid #dee2e6;display:flex;justify-content:space-between;align-items:center}.modal .modal-header h3{margin:0}.modal .modal-header .close-button{background:none;border:none;font-size:1.5rem;cursor:pointer;padding:0;color:#6c757d}.modal .modal-header .close-button:hover{color:#343a40}.modal .modal-body{padding:1rem;height:100vh;display:flex;flex-direction:column}.modal .modal-footer{padding:1rem;border-top:1px solid #dee2e6;display:flex;justify-content:flex-end}\n"] }]
600
+ args: [{ selector: 'dc-cropper-modal', standalone: true, imports: [FormsModule, ImageCropperComponent, ButtonModule, DialogModule, TooltipModule, MessageModule, SelectModule, InputTextModule, SafeHtmlPipe], template: "<div class=\"upload-section\">\n <input type=\"file\" [id]=\"fileInputId\" class=\"file-input\" (change)=\"fileChangeEvent($event)\" />\n <label pButton [for]=\"fileInputId\" [pTooltip]=\"storagePath\" class=\"upload-button\">\n {{ buttonLabel() }}\n </label>\n</div>\n@if(displayDialog) {\n<!-- Cropper Dialog -->\n\n<p-dialog header=\"Recortar imagen\" [(visible)]=\"displayDialog\" [modal]=\"true\" [draggable]=\"false\" [resizable]=\"false\" styleClass=\"cropper-dialog\">\n <!-- Image Settings Section -->\n <div class=\"settings-section\">\n @if(!imgStorageSettings().path) {\n <p-message severity=\"warn\">Developer Note: make sure you have a path to save the image pass object imgStorageSettings</p-message>\n } @if(currentStorage?.url) {\n\n <p-message severity=\"warn\" variant=\"outlined\">\n <div>\n <span class=\"setting-label\">Image will be replaced:</span>\n <img width=\"100\" height=\"Auto\" [src]=\"currentStorage?.url\" />\n </div>\n </p-message>\n\n }\n\n <p-message>\n <b>Estas opciones estan preconfiguradas y no se pueden cambiar</b>\n\n <ul>\n <li> <b>Path to save:</b> {{ storagePath }}< </li>\n <li>\n <b>Resoluciones:</b>\n <span>{{ imgStorageSettings()?.cropSettings?.resolutions }}</span>\n </li>\n </ul>\n </p-message>\n\n <div class=\"setting-item\">\n <span class=\"setting-label\">Aspecto:</span>\n <p class=\"setting-value\">{{ imgStorageSettings()?.cropSettings?.aspectRatio }}</p>\n </div>\n\n <p-select\n [options]=\"aspectRatioOptions\"\n [ngModel]=\"ratioSelected\"\n (ngModelChange)=\"changeRatio($event)\"\n optionLabel=\"description\"\n placeholder=\"Select a ratio\">\n <ng-template pTemplate=\"selectedItem\" let-selectedOption>\n @if(selectedOption) {\n <div class=\"flex items-center gap-2\">\n <div [innerHTML]=\"selectedOption.icon | safeHtml\"></div>\n <div>{{ selectedOption.description }}</div>\n </div>\n }\n </ng-template>\n <ng-template let-ratio pTemplate=\"item\">\n <div class=\"flex items-center gap-2\">\n <div [innerHTML]=\"ratio.icon | safeHtml\"></div>\n <div>{{ ratio.description }}</div>\n </div>\n </ng-template>\n </p-select>\n\n <!-- File Metadata Section -->\n @if (fileMetadata) {\n <div class=\"metadata-section\">\n <span class=\"metadata-item\">tipo: {{ fileMetadata.type }}</span>\n <span class=\"metadata-item\">tama\u00F1o: {{ fileMetadata.size }}</span>\n </div>\n }\n\n <!-- Rename Input -->\n <input\n pInputText\n [disabled]=\"imgStorageSettings()?.fileName\"\n [(ngModel)]=\"renameFile\"\n type=\"text\"\n placeholder=\"Rename File\"\n (ngModelChange)=\"reloadPath()\"\n class=\"rename-input\" />\n\n <h5>Datos adicionales</h5>\n\n <p-select\n [options]=\"MoodStateOptions\"\n [(ngModel)]=\"emotionSelected\"\n (ngModelChange)=\"addEmotion($event)\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select an emotion\" />\n </div>\n\n <!-- Image Cropper -->\n\n <div class=\"cropper-container-father\">\n <image-cropper\n [imageChangedEvent]=\"imageChangedEvent\"\n [maintainAspectRatio]=\"true\"\n [aspectRatio]=\"aspectRatioValue\"\n format=\"webp\"\n [resizeToWidth]=\"resizeToWidth\"\n (imageCropped)=\"onInnerImageCropped($event)\"\n (loadImageFailed)=\"loadImageFailed()\"\n (cropperReady)=\"cropperReady()\"\n [autoCrop]=\"false\">\n </image-cropper>\n </div>\n <!-- Dialog Footer -->\n <ng-template pTemplate=\"footer\">\n <div class=\"dialog-footer\">\n <button pButton class=\"p-button-primary\" (click)=\"simpleCropAndUpload()\"> Recortar y Subir </button>\n </div>\n </ng-template>\n</p-dialog>\n}\n", styles: [":host{display:block}:host ::ng-deep .ngx-ic-overlay{width:100%!important}.upload-section{margin-bottom:1rem}.upload-section .file-input{display:none}.upload-section .upload-button{cursor:pointer}::ng-deep .cropper-dialog{max-width:90vw;width:800px}::ng-deep .cropper-dialog .p-dialog-content{padding:1.5rem}.settings-section{margin-bottom:1.5rem}.settings-section .settings-header{color:var(--text-color-secondary);margin-bottom:1rem}.settings-section .settings-grid{display:grid;gap:1rem;margin-bottom:1.5rem}.settings-section .settings-grid .setting-item .setting-label{font-weight:600;color:var(--text-color);display:block;margin-bottom:.5rem}.settings-section .settings-grid .setting-item .setting-value{color:var(--text-color-secondary);margin:0}.metadata-section{display:flex;gap:1.5rem;margin-bottom:1rem}.metadata-section .metadata-item{color:var(--text-color-secondary)}.rename-section{margin-bottom:5px}.rename-section .rename-input{width:100%;padding:.5rem;border:1px solid var(--surface-border);border-radius:4px}.rename-section .rename-input:disabled{background-color:var(--surface-200);cursor:not-allowed}.cropper-container-father{display:flex;justify-content:center;align-items:center;height:65vh}.dialog-footer{display:flex;justify-content:flex-end;gap:1rem}.btn-crop{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid transparent;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd;border-color:#0d6efd}.btn-crop :hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.file-input{display:none}.btn-upload{cursor:pointer;outline:0;display:inline-block;font-weight:400;line-height:1.5;text-align:center;background-color:transparent;border:1px solid #0d6efd;padding:6px 12px;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;color:#0d6efd}.btn-upload:hover{color:#fff;background-color:#0d6efd}.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;z-index:1000}.modal.show-modal{display:flex;align-items:center;justify-content:center}.modal .modal-content{background-color:#fff;border-radius:8px;width:90%;max-width:800px;max-height:90vh;overflow-y:auto;position:relative}.modal .modal-header{padding:1rem;border-bottom:1px solid #dee2e6;display:flex;justify-content:space-between;align-items:center}.modal .modal-header h3{margin:0}.modal .modal-header .close-button{background:none;border:none;font-size:1.5rem;cursor:pointer;padding:0;color:#6c757d}.modal .modal-header .close-button:hover{color:#343a40}.modal .modal-body{padding:1rem;height:100vh;display:flex;flex-direction:column}.modal .modal-footer{padding:1rem;border-top:1px solid #dee2e6;display:flex;justify-content:flex-end}\n"] }]
424
601
  }], ctorParameters: () => [], propDecorators: { currentStorage: [{
425
602
  type: Input
426
603
  }], imageCropper: [{
@@ -458,9 +635,9 @@ class ImageStoragePreviewComponent {
458
635
  try {
459
636
  this.loading$.next(true);
460
637
  this.error$.next(null);
461
- const storage = getStorage$1();
638
+ const storage = getStorage();
462
639
  const storageRef = ref(storage, this.storagePath);
463
- const result = await listAll$1(storageRef);
640
+ const result = await listAll(storageRef);
464
641
  if (result.items.length === 0) {
465
642
  this.images$.next([]);
466
643
  this.loading$.next(false);
@@ -468,7 +645,7 @@ class ImageStoragePreviewComponent {
468
645
  }
469
646
  const imagePromises = result.items.map(async (itemRef) => {
470
647
  try {
471
- const url = await getDownloadURL$1(itemRef);
648
+ const url = await getDownloadURL(itemRef);
472
649
  const image = {
473
650
  url,
474
651
  // fullPath: itemRef.fullPath,
@@ -501,10 +678,10 @@ class ImageStoragePreviewComponent {
501
678
  selectImage(image) {
502
679
  this.imageSelected.emit(image);
503
680
  }
504
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ImageStoragePreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
505
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ImageStoragePreviewComponent, isStandalone: true, selector: "dc-image-storage-preview", outputs: { imageSelected: "imageSelected" }, ngImport: i0, template: "<div class=\"image-storage-preview-container\">\n <div class=\"header\">\n <h2>Storage Images</h2>\n <button class=\"refresh-btn\" (click)=\"refreshImages()\" [disabled]=\"loading$ | async\">\n @if (!(loading$ | async)) {\n <span>Refresh</span>\n }\n @if (loading$ | async) {\n <span>Loading...</span>\n }\n </button>\n </div>\n\n @if (loading$ | async) {\n <div class=\"loading-container\">\n <div class=\"spinner\"></div>\n <p>Loading images...</p>\n </div>\n }\n\n @if (error$ | async) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error$ | async }}</p>\n <button (click)=\"refreshImages()\">Try Again</button>\n </div>\n }\n\n @if (!(loading$ | async) && !(error$ | async)) {\n <div class=\"images-grid\">\n @if ((images$ | async)?.length) {\n @for (image of images$ | async; track image) {\n <div class=\"image-card\">\n <div class=\"image-container\">\n <img [src]=\"image.url\" [alt]=\"image.name || 'Storage image'\" loading=\"lazy\" />\n </div>\n <div class=\"image-info\">\n <p class=\"image-name\" [title]=\"image.name\">{{ image.name }}</p>\n <div class=\"image-actions\">\n <a [href]=\"image.url\" target=\"_blank\" class=\"action-btn\">View</a>\n <button (click)=\"selectImage(image)\" class=\"action-btn\">Select</button>\n </div>\n </div>\n </div>\n }\n } @else {\n <div class=\"no-images\">\n <p>No images found in the storage path: {{ storagePath }}</p>\n </div>\n }\n <dc-cropper-modal [imgStorageSettings]=\"imgStorageSettings\"></dc-cropper-modal>\n </div>\n }\n</div>\n", styles: [".image-storage-preview-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;padding:20px;max-width:1200px;margin:0 auto}.header{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.header h2{margin:0;color:#333}.refresh-btn{background-color:#4285f4;color:#fff;border:none;border-radius:4px;padding:8px 16px;cursor:pointer;font-size:14px;transition:background-color .2s}.refresh-btn:hover{background-color:#3367d6}.refresh-btn:disabled{background-color:#a9a9a9;cursor:not-allowed}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 0}.spinner{border:4px solid rgba(0,0,0,.1);border-radius:50%;border-top:4px solid #4285f4;width:30px;height:30px;animation:spin 1s linear infinite;margin-bottom:15px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.error-container{background-color:#ffebee;border:1px solid #ffcdd2;border-radius:4px;padding:16px;margin:20px 0;text-align:center}.error-message{color:#d32f2f;margin-bottom:10px}.error-container button{background-color:#d32f2f;color:#fff;border:none;border-radius:4px;padding:8px 16px;cursor:pointer;font-size:14px}.images-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:20px}.image-card{border-radius:8px;overflow:hidden;box-shadow:0 2px 10px #0000001a;transition:transform .2s,box-shadow .2s;background-color:#fff}.image-card:hover{transform:translateY(-5px);box-shadow:0 5px 15px #00000026}.image-container{height:200px;overflow:hidden;position:relative;background-color:#f5f5f5}.image-container img{width:100%;height:100%;object-fit:cover;transition:transform .3s}.image-card:hover .image-container img{transform:scale(1.05)}.image-info{padding:15px}.image-name{margin:0 0 10px;font-size:14px;font-weight:500;color:#333;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.image-actions{display:flex;justify-content:flex-end}.action-btn{background-color:#4285f4;color:#fff;text-decoration:none;border-radius:4px;padding:6px 12px;font-size:12px;transition:background-color .2s}.action-btn:hover{background-color:#3367d6}.no-images{grid-column:1 / -1;text-align:center;padding:40px 0;color:#757575;background-color:#f5f5f5;border-radius:8px}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: CropperComponentModal, selector: "dc-cropper-modal", inputs: ["imgStorageSettings", "buttonLabel", "currentStorage"], outputs: ["imageUploaded", "onImageCropped", "onFileSelected"] }] }); }
681
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ImageStoragePreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
682
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: ImageStoragePreviewComponent, isStandalone: true, selector: "dc-image-storage-preview", outputs: { imageSelected: "imageSelected" }, ngImport: i0, template: "<div class=\"image-storage-preview-container\">\n <div class=\"header\">\n <h2>Storage Images</h2>\n <button class=\"refresh-btn\" (click)=\"refreshImages()\" [disabled]=\"loading$ | async\">\n @if (!(loading$ | async)) {\n <span>Refresh</span>\n }\n @if (loading$ | async) {\n <span>Loading...</span>\n }\n </button>\n </div>\n\n @if (loading$ | async) {\n <div class=\"loading-container\">\n <div class=\"spinner\"></div>\n <p>Loading images...</p>\n </div>\n }\n\n @if (error$ | async) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error$ | async }}</p>\n <button (click)=\"refreshImages()\">Try Again</button>\n </div>\n }\n\n @if (!(loading$ | async) && !(error$ | async)) {\n <div class=\"images-grid\">\n @if ((images$ | async)?.length) {\n @for (image of images$ | async; track image) {\n <div class=\"image-card\">\n <div class=\"image-container\">\n <img [src]=\"image.url\" [alt]=\"image.name || 'Storage image'\" loading=\"lazy\" />\n </div>\n <div class=\"image-info\">\n <p class=\"image-name\" [title]=\"image.name\">{{ image.name }}</p>\n <div class=\"image-actions\">\n <a [href]=\"image.url\" target=\"_blank\" class=\"action-btn\">View</a>\n <button (click)=\"selectImage(image)\" class=\"action-btn\">Select</button>\n </div>\n </div>\n </div>\n }\n } @else {\n <div class=\"no-images\">\n <p>No images found in the storage path: {{ storagePath }}</p>\n </div>\n }\n <dc-cropper-modal [imgStorageSettings]=\"imgStorageSettings\"></dc-cropper-modal>\n </div>\n }\n</div>\n", styles: [".image-storage-preview-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;padding:20px;max-width:1200px;margin:0 auto}.header{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.header h2{margin:0;color:#333}.refresh-btn{background-color:#4285f4;color:#fff;border:none;border-radius:4px;padding:8px 16px;cursor:pointer;font-size:14px;transition:background-color .2s}.refresh-btn:hover{background-color:#3367d6}.refresh-btn:disabled{background-color:#a9a9a9;cursor:not-allowed}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 0}.spinner{border:4px solid rgba(0,0,0,.1);border-radius:50%;border-top:4px solid #4285f4;width:30px;height:30px;animation:spin 1s linear infinite;margin-bottom:15px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.error-container{background-color:#ffebee;border:1px solid #ffcdd2;border-radius:4px;padding:16px;margin:20px 0;text-align:center}.error-message{color:#d32f2f;margin-bottom:10px}.error-container button{background-color:#d32f2f;color:#fff;border:none;border-radius:4px;padding:8px 16px;cursor:pointer;font-size:14px}.images-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:20px}.image-card{border-radius:8px;overflow:hidden;box-shadow:0 2px 10px #0000001a;transition:transform .2s,box-shadow .2s;background-color:#fff}.image-card:hover{transform:translateY(-5px);box-shadow:0 5px 15px #00000026}.image-container{height:200px;overflow:hidden;position:relative;background-color:#f5f5f5}.image-container img{width:100%;height:100%;object-fit:cover;transition:transform .3s}.image-card:hover .image-container img{transform:scale(1.05)}.image-info{padding:15px}.image-name{margin:0 0 10px;font-size:14px;font-weight:500;color:#333;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.image-actions{display:flex;justify-content:flex-end}.action-btn{background-color:#4285f4;color:#fff;text-decoration:none;border-radius:4px;padding:6px 12px;font-size:12px;transition:background-color .2s}.action-btn:hover{background-color:#3367d6}.no-images{grid-column:1 / -1;text-align:center;padding:40px 0;color:#757575;background-color:#f5f5f5;border-radius:8px}\n"], dependencies: [{ kind: "component", type: CropperComponentModal, selector: "dc-cropper-modal", inputs: ["imgStorageSettings", "buttonLabel", "currentStorage"], outputs: ["imageUploaded", "onImageCropped", "onFileSelected"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
506
683
  }
507
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ImageStoragePreviewComponent, decorators: [{
684
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ImageStoragePreviewComponent, decorators: [{
508
685
  type: Component,
509
686
  args: [{ selector: 'dc-image-storage-preview', standalone: true, imports: [AsyncPipe, CropperComponentModal], template: "<div class=\"image-storage-preview-container\">\n <div class=\"header\">\n <h2>Storage Images</h2>\n <button class=\"refresh-btn\" (click)=\"refreshImages()\" [disabled]=\"loading$ | async\">\n @if (!(loading$ | async)) {\n <span>Refresh</span>\n }\n @if (loading$ | async) {\n <span>Loading...</span>\n }\n </button>\n </div>\n\n @if (loading$ | async) {\n <div class=\"loading-container\">\n <div class=\"spinner\"></div>\n <p>Loading images...</p>\n </div>\n }\n\n @if (error$ | async) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error$ | async }}</p>\n <button (click)=\"refreshImages()\">Try Again</button>\n </div>\n }\n\n @if (!(loading$ | async) && !(error$ | async)) {\n <div class=\"images-grid\">\n @if ((images$ | async)?.length) {\n @for (image of images$ | async; track image) {\n <div class=\"image-card\">\n <div class=\"image-container\">\n <img [src]=\"image.url\" [alt]=\"image.name || 'Storage image'\" loading=\"lazy\" />\n </div>\n <div class=\"image-info\">\n <p class=\"image-name\" [title]=\"image.name\">{{ image.name }}</p>\n <div class=\"image-actions\">\n <a [href]=\"image.url\" target=\"_blank\" class=\"action-btn\">View</a>\n <button (click)=\"selectImage(image)\" class=\"action-btn\">Select</button>\n </div>\n </div>\n </div>\n }\n } @else {\n <div class=\"no-images\">\n <p>No images found in the storage path: {{ storagePath }}</p>\n </div>\n }\n <dc-cropper-modal [imgStorageSettings]=\"imgStorageSettings\"></dc-cropper-modal>\n </div>\n }\n</div>\n", styles: [".image-storage-preview-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;padding:20px;max-width:1200px;margin:0 auto}.header{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.header h2{margin:0;color:#333}.refresh-btn{background-color:#4285f4;color:#fff;border:none;border-radius:4px;padding:8px 16px;cursor:pointer;font-size:14px;transition:background-color .2s}.refresh-btn:hover{background-color:#3367d6}.refresh-btn:disabled{background-color:#a9a9a9;cursor:not-allowed}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 0}.spinner{border:4px solid rgba(0,0,0,.1);border-radius:50%;border-top:4px solid #4285f4;width:30px;height:30px;animation:spin 1s linear infinite;margin-bottom:15px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.error-container{background-color:#ffebee;border:1px solid #ffcdd2;border-radius:4px;padding:16px;margin:20px 0;text-align:center}.error-message{color:#d32f2f;margin-bottom:10px}.error-container button{background-color:#d32f2f;color:#fff;border:none;border-radius:4px;padding:8px 16px;cursor:pointer;font-size:14px}.images-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:20px}.image-card{border-radius:8px;overflow:hidden;box-shadow:0 2px 10px #0000001a;transition:transform .2s,box-shadow .2s;background-color:#fff}.image-card:hover{transform:translateY(-5px);box-shadow:0 5px 15px #00000026}.image-container{height:200px;overflow:hidden;position:relative;background-color:#f5f5f5}.image-container img{width:100%;height:100%;object-fit:cover;transition:transform .3s}.image-card:hover .image-container img{transform:scale(1.05)}.image-info{padding:15px}.image-name{margin:0 0 10px;font-size:14px;font-weight:500;color:#333;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.image-actions{display:flex;justify-content:flex-end}.action-btn{background-color:#4285f4;color:#fff;text-decoration:none;border-radius:4px;padding:6px 12px;font-size:12px;transition:background-color .2s}.action-btn:hover{background-color:#3367d6}.no-images{grid-column:1 / -1;text-align:center;padding:40px 0;color:#757575;background-color:#f5f5f5;border-radius:8px}\n"] }]
510
687
  }], ctorParameters: () => [] });
@@ -512,30 +689,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
512
689
  class SimpleUploaderComponent {
513
690
  constructor() {
514
691
  this.multiImagesStorageService = inject(MultiImagesStorageService);
515
- this.storagePath = input.required();
516
- this.buttonLabel = input('Upload File');
517
- this.accept = input('*/*');
518
- this.disabled = input(false);
692
+ this.storagePath = input.required(...(ngDevMode ? [{ debugName: "storagePath" }] : []));
693
+ this.buttonLabel = input('Upload File', ...(ngDevMode ? [{ debugName: "buttonLabel" }] : []));
694
+ this.accept = input('*/*', ...(ngDevMode ? [{ debugName: "accept" }] : []));
695
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
696
+ this.metadata = input({}, ...(ngDevMode ? [{ debugName: "metadata" }] : []));
519
697
  this.fileUploaded = output();
520
698
  this.uploadError = output();
521
- this.isLoading = signal(false);
699
+ this.isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
700
+ this.displayDialog = signal(false, ...(ngDevMode ? [{ debugName: "displayDialog" }] : []));
701
+ this.fileSelected = signal(null, ...(ngDevMode ? [{ debugName: "fileSelected" }] : []));
702
+ this.moodSelected = signal(null, ...(ngDevMode ? [{ debugName: "moodSelected" }] : []));
703
+ this.eventSelected = signal(null, ...(ngDevMode ? [{ debugName: "eventSelected" }] : []));
704
+ this.metadataInput = {};
705
+ this.MoodStateOptions = MoodStateOptions;
706
+ this.CharacterEventActions = CharacterEventActions;
522
707
  this.fileInputId = `file-upload-${Math.random().toString(36).substring(2, 11)}`;
523
708
  }
709
+ objectKeys(obj) {
710
+ return Object.keys(obj);
711
+ }
712
+ openDialog() {
713
+ this.metadataInput = { ...this.metadata() };
714
+ this.displayDialog.set(true);
715
+ }
524
716
  triggerFileInputClick(fileInput) {
525
717
  fileInput.click();
526
718
  }
527
- async onFileSelected(event) {
719
+ onFileSelected(event) {
528
720
  const fileInput = event.target;
529
721
  const file = fileInput.files?.[0];
722
+ if (file) {
723
+ this.fileSelected.set(file);
724
+ }
725
+ }
726
+ async uploadFile() {
727
+ const file = this.fileSelected();
530
728
  if (file) {
531
729
  this.isLoading.set(true);
730
+ const metadata = {
731
+ // ...this.metadataInput,
732
+ moodState: this.moodSelected(),
733
+ event: this.eventSelected(),
734
+ };
532
735
  try {
533
- const result = await this.multiImagesStorageService.uploadGenericFile(file, this.storagePath());
736
+ const result = await this.multiImagesStorageService.uploadGenericFile(file, this.storagePath(), metadata);
737
+ result.metadata = metadata;
534
738
  if (result) {
535
739
  this.fileUploaded.emit(result);
536
740
  }
537
741
  else {
538
- // This case might occur if the service's uploadGenericFile returns null without throwing an error
539
742
  this.uploadError.emit({ error: 'Upload failed and no specific error was provided by the service.' });
540
743
  }
541
744
  }
@@ -545,17 +748,19 @@ class SimpleUploaderComponent {
545
748
  }
546
749
  finally {
547
750
  this.isLoading.set(false);
548
- // Reset file input to allow uploading the same file again if needed
549
- fileInput.value = '';
751
+ this.displayDialog.set(false);
752
+ this.fileSelected.set(null);
753
+ this.moodSelected.set(null);
754
+ this.eventSelected.set(null);
550
755
  }
551
756
  }
552
757
  }
553
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: SimpleUploaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
554
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.4", type: SimpleUploaderComponent, isStandalone: true, selector: "dc-simple-uploader", inputs: { storagePath: { classPropertyName: "storagePath", publicName: "storagePath", isSignal: true, isRequired: true, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileUploaded: "fileUploaded", uploadError: "uploadError" }, ngImport: i0, template: "<input #fileInput type=\"file\" [id]=\"fileInputId\" (change)=\"onFileSelected($event)\" [accept]=\"accept()\" style=\"display: none\" />\n<p-button\n size=\"large\"\n [label]=\"buttonLabel()\"\n (click)=\"triggerFileInputClick(fileInput)\"\n [loading]=\"isLoading()\"\n [disabled]=\"disabled() || isLoading()\"\n pTooltip=\"Un v\u00EDdeo que muestre la imagen principal animada\"></p-button>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }] }); }
758
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SimpleUploaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
759
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: SimpleUploaderComponent, isStandalone: true, selector: "dc-simple-uploader", inputs: { storagePath: { classPropertyName: "storagePath", publicName: "storagePath", isSignal: true, isRequired: true, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileUploaded: "fileUploaded", uploadError: "uploadError" }, ngImport: i0, template: "<p-button\n size=\"large\"\n [label]=\"buttonLabel()\"\n (click)=\"openDialog()\"\n [loading]=\"isLoading()\"\n [disabled]=\"disabled() || isLoading()\"\n pTooltip=\"Upload a file with metadata\"></p-button>\n\n@if(displayDialog()){\n<p-dialog\n header=\"Upload File\"\n [(visible)]=\"displayDialog\"\n [modal]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [contentStyle]=\"{ width: '50vw', height: '50vh' }\">\n <div class=\"upload-dialog\">\n @if(!fileSelected()){\n <div class=\"file-input-container\">\n <input #fileInput type=\"file\" [id]=\"fileInputId\" (change)=\"onFileSelected($event)\" [accept]=\"accept()\" style=\"display: none\" />\n <p-button label=\"Select File\" (click)=\"triggerFileInputClick(fileInput)\"></p-button>\n </div>\n } @else {\n <div class=\"file-details\">\n <p>File: {{ fileSelected()?.name }}</p>\n <p>Size: {{ fileSelected()?.size }} bytes</p>\n </div>\n\n <div class=\"metadata-container\">\n <h5>Metadata</h5>\n <div class=\"p-fluid\">\n @for (key of objectKeys(metadata()); track key) {\n <div class=\"p-field\">\n <label [for]=\"key\">{{ key }}</label>\n <input pInputText [id]=\"key\" [(ngModel)]=\"metadataInput[key]\" />\n </div>\n }\n\n <div class=\"p-field\">\n <label for=\"emotion\">Emotion</label>\n <br />\n <p-select [options]=\"MoodStateOptions\" [(ngModel)]=\"moodSelected\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select an emotion\"></p-select>\n </div>\n <div class=\"p-field\">\n <label for=\"emotion\">Event</label>\n <br />\n <p-select\n [options]=\"CharacterEventActions\"\n [(ngModel)]=\"eventSelected\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select an event\"></p-select>\n </div>\n </div>\n </div>\n }\n </div>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"dialog-footer\">\n <p-button label=\"Cancel\" styleClass=\"p-button-secondary\" (click)=\"displayDialog.set(false)\"></p-button>\n <p-button label=\"Upload\" (click)=\"uploadFile()\" [disabled]=\"!fileSelected() || isLoading()\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i7.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
555
760
  }
556
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: SimpleUploaderComponent, decorators: [{
761
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SimpleUploaderComponent, decorators: [{
557
762
  type: Component,
558
- args: [{ selector: 'dc-simple-uploader', standalone: true, imports: [CommonModule, FormsModule, ButtonModule, TooltipModule], template: "<input #fileInput type=\"file\" [id]=\"fileInputId\" (change)=\"onFileSelected($event)\" [accept]=\"accept()\" style=\"display: none\" />\n<p-button\n size=\"large\"\n [label]=\"buttonLabel()\"\n (click)=\"triggerFileInputClick(fileInput)\"\n [loading]=\"isLoading()\"\n [disabled]=\"disabled() || isLoading()\"\n pTooltip=\"Un v\u00EDdeo que muestre la imagen principal animada\"></p-button>\n" }]
763
+ args: [{ selector: 'dc-simple-uploader', standalone: true, imports: [CommonModule, FormsModule, ButtonModule, TooltipModule, DialogModule, InputTextModule, SelectModule], template: "<p-button\n size=\"large\"\n [label]=\"buttonLabel()\"\n (click)=\"openDialog()\"\n [loading]=\"isLoading()\"\n [disabled]=\"disabled() || isLoading()\"\n pTooltip=\"Upload a file with metadata\"></p-button>\n\n@if(displayDialog()){\n<p-dialog\n header=\"Upload File\"\n [(visible)]=\"displayDialog\"\n [modal]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [contentStyle]=\"{ width: '50vw', height: '50vh' }\">\n <div class=\"upload-dialog\">\n @if(!fileSelected()){\n <div class=\"file-input-container\">\n <input #fileInput type=\"file\" [id]=\"fileInputId\" (change)=\"onFileSelected($event)\" [accept]=\"accept()\" style=\"display: none\" />\n <p-button label=\"Select File\" (click)=\"triggerFileInputClick(fileInput)\"></p-button>\n </div>\n } @else {\n <div class=\"file-details\">\n <p>File: {{ fileSelected()?.name }}</p>\n <p>Size: {{ fileSelected()?.size }} bytes</p>\n </div>\n\n <div class=\"metadata-container\">\n <h5>Metadata</h5>\n <div class=\"p-fluid\">\n @for (key of objectKeys(metadata()); track key) {\n <div class=\"p-field\">\n <label [for]=\"key\">{{ key }}</label>\n <input pInputText [id]=\"key\" [(ngModel)]=\"metadataInput[key]\" />\n </div>\n }\n\n <div class=\"p-field\">\n <label for=\"emotion\">Emotion</label>\n <br />\n <p-select [options]=\"MoodStateOptions\" [(ngModel)]=\"moodSelected\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select an emotion\"></p-select>\n </div>\n <div class=\"p-field\">\n <label for=\"emotion\">Event</label>\n <br />\n <p-select\n [options]=\"CharacterEventActions\"\n [(ngModel)]=\"eventSelected\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select an event\"></p-select>\n </div>\n </div>\n </div>\n }\n </div>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"dialog-footer\">\n <p-button label=\"Cancel\" styleClass=\"p-button-secondary\" (click)=\"displayDialog.set(false)\"></p-button>\n <p-button label=\"Upload\" (click)=\"uploadFile()\" [disabled]=\"!fileSelected() || isLoading()\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n}\n" }]
559
764
  }], ctorParameters: () => [] });
560
765
 
561
766
  class DCFilesCacheService {
@@ -568,7 +773,7 @@ class DCFilesCacheService {
568
773
  return this.files[path];
569
774
  }
570
775
  else {
571
- const url = await getDownloadURL(ref$1(this.storage, path));
776
+ const url = await getDownloadURL(ref(this.storage, path));
572
777
  const localUrl = await this.donwloadFileAndGetLocalURL(url);
573
778
  this.files[path] = localUrl;
574
779
  return localUrl;
@@ -594,15 +799,15 @@ class DCFilesCacheService {
594
799
  const blob = await this.getBlob(url);
595
800
  return URL.createObjectURL(blob);
596
801
  }
597
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCFilesCacheService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
598
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCFilesCacheService, providedIn: 'root' }); }
802
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCFilesCacheService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
803
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCFilesCacheService, providedIn: 'root' }); }
599
804
  }
600
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCFilesCacheService, decorators: [{
805
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCFilesCacheService, decorators: [{
601
806
  type: Injectable,
602
807
  args: [{
603
808
  providedIn: 'root',
604
809
  }]
605
- }], ctorParameters: () => [] });
810
+ }] });
606
811
 
607
812
  class MultiObjectStorageService {
608
813
  constructor() {
@@ -692,20 +897,20 @@ class MultiObjectStorageService {
692
897
  };
693
898
  return meta;
694
899
  }
695
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: MultiObjectStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
696
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: MultiObjectStorageService, providedIn: 'root' }); }
900
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: MultiObjectStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
901
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: MultiObjectStorageService, providedIn: 'root' }); }
697
902
  }
698
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: MultiObjectStorageService, decorators: [{
903
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: MultiObjectStorageService, decorators: [{
699
904
  type: Injectable,
700
905
  args: [{
701
906
  providedIn: 'root',
702
907
  }]
703
908
  }] });
704
909
 
705
- class CsaAssetsLoaderComponent {
910
+ class AssetsLoaderComponent {
706
911
  constructor() {
707
- this.assets = input.required();
708
- this.storagePath = input.required();
912
+ this.assets = input.required(...(ngDevMode ? [{ debugName: "assets" }] : []));
913
+ this.storagePath = input.required(...(ngDevMode ? [{ debugName: "storagePath" }] : []));
709
914
  this.assetsChange = output();
710
915
  this.assetUpdate = output();
711
916
  this.onFileSelected = output();
@@ -713,18 +918,18 @@ class CsaAssetsLoaderComponent {
713
918
  this.bannerImgSettings = computed(() => ({
714
919
  path: this.storagePath(),
715
920
  fileName: undefined,
716
- cropSettings: { aspectRatio: AspectType.Rectangle, resolutions: [ResolutionType.MediumLarge], resizeToWidth: 700 },
717
- }));
921
+ cropSettings: { aspectRatio: AspectType.Rectangle, resolutions: [ResolutionType.MediumLarge], resizeToWidth: 850 },
922
+ }), ...(ngDevMode ? [{ debugName: "bannerImgSettings" }] : []));
718
923
  this.imageStorageSettings = computed(() => ({
719
924
  path: this.storagePath(),
720
925
  fileName: undefined,
721
926
  cropSettings: { aspectRatio: AspectType.Vertical_2_3, resolutions: [ResolutionType.MediumLarge], resizeToWidth: 500 },
722
- }));
927
+ }), ...(ngDevMode ? [{ debugName: "imageStorageSettings" }] : []));
723
928
  this.stickerStorageSettings = computed(() => ({
724
929
  path: `${this.storagePath()}/stickers`,
725
930
  fileName: undefined,
726
931
  cropSettings: { aspectRatio: AspectType.Square, resolutions: [ResolutionType.MediumLarge], resizeToWidth: 400 },
727
- }));
932
+ }), ...(ngDevMode ? [{ debugName: "stickerStorageSettings" }] : []));
728
933
  }
729
934
  onImageUploaded(event, type = 'image') {
730
935
  const currentAssets = this.assets() ?? { image: null, banner: null, stickers: [] };
@@ -753,6 +958,15 @@ class CsaAssetsLoaderComponent {
753
958
  }
754
959
  const updatedField = { motion: { url: event.url } };
755
960
  const newAssets = { ...this.assets(), ...updatedField };
961
+ // Emit only the update field
962
+ this.assetUpdate.emit({ assets: updatedField });
963
+ // Assets Changes emit the new object
964
+ this.assetsChange.emit(newAssets);
965
+ }
966
+ onMotionAdded(event) {
967
+ const currentAssets = this.assets() ?? { motions: [] };
968
+ const updatedField = { motions: [...(currentAssets.motions || []), event] };
969
+ const newAssets = { ...currentAssets, ...updatedField };
756
970
  this.assetUpdate.emit({ assets: updatedField });
757
971
  this.assetsChange.emit(newAssets);
758
972
  }
@@ -768,12 +982,54 @@ class CsaAssetsLoaderComponent {
768
982
  this.assetUpdate.emit({ assets: updatedField });
769
983
  this.assetsChange.emit(newAssets);
770
984
  }
771
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CsaAssetsLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
772
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: CsaAssetsLoaderComponent, isStandalone: true, selector: "assets-loader", inputs: { assets: { classPropertyName: "assets", publicName: "assets", isSignal: true, isRequired: true, transformFunction: null }, storagePath: { classPropertyName: "storagePath", publicName: "storagePath", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { assetsChange: "assetsChange", assetUpdate: "assetUpdate", onFileSelected: "onFileSelected" }, ngImport: i0, template: "<div class=\"assets-container\">\n <div class=\"assets-card\">\n <p-message severity=\"info\">\n <div class=\"upload-buttons\">\n <div>\n <dc-cropper-modal\n id=\"cropperCardImage\"\n #cropperCardImage\n [buttonLabel]=\"assets()?.image?.url ? 'Cambiar imagen' : 'Cargar una imagen'\"\n [imgStorageSettings]=\"imageStorageSettings()\"\n [currentStorage]=\"assets()?.image\"\n (imageUploaded)=\"onImageUploaded($event, 'image')\"\n (onFileSelected)=\"onFileSelected.emit($event)\"></dc-cropper-modal>\n </div>\n\n <dc-simple-uploader\n [buttonLabel]=\"'Agregar movimiento'\"\n (fileUploaded)=\"onMotionUploaded($event)\"\n [storagePath]=\"storagePath() + '/movimientos/file'\"\n [accept]=\"'video/*'\"></dc-simple-uploader>\n\n <dc-cropper-modal\n #cropperBanner\n id=\"cropperBanner\"\n [buttonLabel]=\"assets()?.banner?.url ? 'Cambiar el banner' : 'Cargar un banner'\"\n [imgStorageSettings]=\"bannerImgSettings()\"\n [currentStorage]=\"assets()?.banner\"\n (imageUploaded)=\"onImageUploaded($event, 'banner')\"></dc-cropper-modal>\n\n <dc-cropper-modal\n id=\"cropperStickers\"\n #cropperStickers\n [buttonLabel]=\"'agregar sticker'\"\n [imgStorageSettings]=\"stickerStorageSettings()\"\n (imageUploaded)=\"onImageUploaded($event, 'sticker')\"></dc-cropper-modal>\n </div>\n </p-message>\n <!-- Banner -->\n\n <div class=\"preview-container\">\n <img [src]=\"assets()?.banner?.url || 'assets/defaults/images/default_banner.webp'\" class=\"main-banner-image-card\" />\n <img [src]=\"assets()?.image?.url || 'assets/defaults/images/default_2_3.webp'\" class=\"main-image-card\" />\n <video class=\"main-motion-card\" [src]=\"assets()?.motion?.url\" autoplay loop muted playsinline></video>\n </div>\n\n <div class=\"stickers-container\">\n @for (sticker of assets()?.stickers; track sticker.url) {\n <div class=\"sticker-wrapper\">\n <img width=\"100\" [src]=\"sticker.url\" alt=\"\" />\n <p-button (click)=\"removeSticker(sticker)\" class=\"remove-sticker\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" />\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".main-image-card{max-width:220px;display:block;border-radius:8px;position:absolute;bottom:-100px;right:20px;transform:none;z-index:1;box-shadow:0 4px 8px #0003}@media (max-width: 1300px){.main-image-card{max-width:170px}}@media (max-width: 768px){.main-image-card{max-width:130px}}.main-motion-card{max-width:220px;display:block;border-radius:8px;position:absolute;bottom:-100px;left:20px;transform:none;z-index:1;box-shadow:0 4px 8px #0003}@media (max-width: 1300px){.main-motion-card{max-width:170px}}@media (max-width: 768px){.main-motion-card{max-width:130px}}.main-banner-image-card{display:block;width:100%;max-height:400px;object-fit:cover;border-radius:8px}.remove-sticker{position:absolute;top:5px;right:5px}.assets-container{position:relative;min-height:60px}.assets-card{border:1px dashed rgba(12,19,142,.1215686275);padding:4px;border-radius:15px}.upload-buttons{display:flex;gap:10px}.preview-container{position:relative;margin-bottom:100px}.stickers-container{display:flex;flex-wrap:wrap;gap:10px}.sticker-wrapper{position:relative}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CropperComponentModal, selector: "dc-cropper-modal", inputs: ["imgStorageSettings", "buttonLabel", "currentStorage"], outputs: ["imageUploaded", "onImageCropped", "onFileSelected"] }, { kind: "component", type: SimpleUploaderComponent, selector: "dc-simple-uploader", inputs: ["storagePath", "buttonLabel", "accept", "disabled"], outputs: ["fileUploaded", "uploadError"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i6.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }] }); }
985
+ removeMotion(motion) {
986
+ const path = extractPath(motion);
987
+ if (path) {
988
+ this.storageService.deleteImage(path);
989
+ }
990
+ const currentMotions = this.assets()?.motions ?? [];
991
+ const updatedMotions = currentMotions.filter((m) => m.url !== motion.url);
992
+ const updatedField = { motions: updatedMotions };
993
+ const newAssets = { ...this.assets(), ...updatedField };
994
+ this.assetUpdate.emit({ assets: updatedField });
995
+ this.assetsChange.emit(newAssets);
996
+ }
997
+ removeMainMotion() {
998
+ const motionToRemove = this.assets()?.motion;
999
+ if (motionToRemove?.url) {
1000
+ const path = extractPath(motionToRemove);
1001
+ if (path) {
1002
+ this.storageService.deleteImage(path);
1003
+ }
1004
+ const updatedField = { motion: null };
1005
+ const newAssets = { ...this.assets(), motion: null };
1006
+ this.assetUpdate.emit({ assets: updatedField });
1007
+ this.assetsChange.emit(newAssets);
1008
+ }
1009
+ }
1010
+ onVideoEnded(video) {
1011
+ video.pause();
1012
+ this.reverseInterval = setInterval(() => {
1013
+ if (video.currentTime <= 0) {
1014
+ clearInterval(this.reverseInterval);
1015
+ video.play();
1016
+ }
1017
+ else {
1018
+ video.currentTime -= 0.03;
1019
+ }
1020
+ }, 30);
1021
+ }
1022
+ ngOnDestroy() {
1023
+ if (this.reverseInterval) {
1024
+ clearInterval(this.reverseInterval);
1025
+ }
1026
+ }
1027
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AssetsLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1028
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AssetsLoaderComponent, isStandalone: true, selector: "assets-loader", inputs: { assets: { classPropertyName: "assets", publicName: "assets", isSignal: true, isRequired: true, transformFunction: null }, storagePath: { classPropertyName: "storagePath", publicName: "storagePath", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { assetsChange: "assetsChange", assetUpdate: "assetUpdate", onFileSelected: "onFileSelected" }, ngImport: i0, template: "<div class=\"assets-container\">\n <div class=\"assets-card\">\n <p-message severity=\"info\">\n <div class=\"upload-buttons\">\n <div>\n <dc-cropper-modal\n id=\"cropperCardImage\"\n #cropperCardImage\n [buttonLabel]=\"assets()?.image?.url ? 'Cambiar imagen' : 'Cargar una imagen'\"\n [imgStorageSettings]=\"imageStorageSettings()\"\n [currentStorage]=\"assets()?.image\"\n (imageUploaded)=\"onImageUploaded($event, 'image')\"\n (onFileSelected)=\"onFileSelected.emit($event)\"></dc-cropper-modal>\n </div>\n\n <dc-simple-uploader\n [buttonLabel]=\"assets()?.motion?.url ? 'Cambiar video principal' : 'Agregar video principal'\"\n (fileUploaded)=\"onMotionUploaded($event)\"\n [storagePath]=\"storagePath() + '/motions/file'\"\n [accept]=\"'video/*'\"></dc-simple-uploader>\n\n <dc-simple-uploader\n [buttonLabel]=\"'Agregar Movimientos'\"\n (fileUploaded)=\"onMotionAdded($event)\"\n [storagePath]=\"storagePath() + '/motions/file'\"\n [accept]=\"'video/*'\"></dc-simple-uploader>\n\n <dc-cropper-modal\n #cropperBanner\n id=\"cropperBanner\"\n [buttonLabel]=\"assets()?.banner?.url ? 'Cambiar el banner' : 'Cargar un banner'\"\n [imgStorageSettings]=\"bannerImgSettings()\"\n [currentStorage]=\"assets()?.banner\"\n (imageUploaded)=\"onImageUploaded($event, 'banner')\"></dc-cropper-modal>\n\n <dc-cropper-modal\n id=\"cropperStickers\"\n #cropperStickers\n [buttonLabel]=\"'Agregar sticker'\"\n [imgStorageSettings]=\"stickerStorageSettings()\"\n (imageUploaded)=\"onImageUploaded($event, 'sticker')\"></dc-cropper-modal>\n </div>\n </p-message>\n <!-- Banner -->\n\n <div class=\"preview-container\">\n <img [src]=\"assets()?.banner?.url || 'assets/defaults/images/default_banner.webp'\" class=\"main-banner-image-card\" />\n <div class=\"main-image-card\">\n <img [src]=\"assets()?.image?.url || 'assets/defaults/images/default_2_3.webp'\" />\n </div>\n\n <div class=\"motion-container\">\n <video #videoPlayer class=\"main-motion-card\" [src]=\"assets()?.motion?.url\" (ended)=\"onVideoEnded(videoPlayer)\" autoplay muted playsinline></video>\n @if(assets()?.motion?.url){\n <p-button class=\"remove-main-motion-button\" (click)=\"removeMainMotion()\" [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-trash\" severity=\"danger\"></p-button>\n }\n </div>\n </div>\n\n <div class=\"stickers-container\">\n @for (sticker of assets()?.stickers; track sticker.url) {\n <div class=\"sticker-wrapper\">\n <img width=\"100\" [src]=\"sticker.url\" alt=\"\" />\n <p-button (click)=\"removeSticker(sticker)\" class=\"remove-sticker\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" />\n </div>\n }\n </div>\n\n <div class=\"motions-container\">\n @for (motion of assets()?.motions; track motion.url) {\n <div class=\"motion-wrapper\">\n <video width=\"150\" [src]=\"motion.url\" controls playsinline preload=\"none\"></video>\n <p-button (click)=\"removeMotion(motion)\" class=\"remove-motion-button\" icon=\"pi pi-trash\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\"></p-button>\n @if(motion.metadata?.moodState){\n <p-tag style=\"position: absolute; top: 4px; left: 4px\" severity=\"secondary\" [value]=\"motion.metadata?.moodState\" />\n } @if(motion.metadata?.event){\n <p-tag style=\"position: absolute; top: 4px; left: 4px\" severity=\"warn\" [value]=\"motion.metadata?.event\" />\n }\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".main-image-card{max-width:220px;display:block;border-radius:8px;position:absolute;bottom:-100px;left:20px;transform:none;z-index:1;box-shadow:0 4px 8px #0003;overflow:hidden}@media (max-width: 1300px){.main-image-card{max-width:170px}}@media (max-width: 768px){.main-image-card{max-width:130px}}.main-motion-card{max-width:100%;display:block;border-radius:8px}.main-banner-image-card{display:block;width:100%;max-height:400px;object-fit:cover;border-radius:8px}.remove-sticker{position:absolute;top:5px;right:5px}.assets-container{position:relative;min-height:60px}.assets-card{border:1px dashed rgba(12,19,142,.1215686275);padding:4px;border-radius:15px}.upload-buttons{display:flex;gap:10px}.preview-container{position:relative;margin-bottom:100px}.stickers-container{display:flex;flex-wrap:wrap;gap:10px}.sticker-wrapper{position:relative}.motion-container{position:absolute;bottom:-100px;right:20px;z-index:1;box-shadow:0 4px 8px #0003;max-width:220px;border-radius:8px;overflow:hidden}@media (max-width: 1300px){.motion-container{max-width:170px}}@media (max-width: 768px){.motion-container{max-width:130px}}.remove-main-motion-button{position:absolute;top:10px;right:10px;z-index:2}.motions-container{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px}.motion-wrapper{position:relative;width:150px;border-radius:8px;overflow:hidden;box-shadow:0 2px 4px #0000001a}.motion-wrapper video{min-height:220px;display:block;background-color:#f0f0f0}.remove-motion-button{position:absolute;top:5px;right:5px;z-index:2}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CropperComponentModal, selector: "dc-cropper-modal", inputs: ["imgStorageSettings", "buttonLabel", "currentStorage"], outputs: ["imageUploaded", "onImageCropped", "onFileSelected"] }, { kind: "component", type: SimpleUploaderComponent, selector: "dc-simple-uploader", inputs: ["storagePath", "buttonLabel", "accept", "disabled", "metadata"], outputs: ["fileUploaded", "uploadError"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i6.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i3$1.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }] }); }
773
1029
  }
774
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CsaAssetsLoaderComponent, decorators: [{
1030
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AssetsLoaderComponent, decorators: [{
775
1031
  type: Component,
776
- args: [{ selector: 'assets-loader', standalone: true, imports: [CommonModule, CropperComponentModal, SimpleUploaderComponent, ButtonModule, MessageModule], template: "<div class=\"assets-container\">\n <div class=\"assets-card\">\n <p-message severity=\"info\">\n <div class=\"upload-buttons\">\n <div>\n <dc-cropper-modal\n id=\"cropperCardImage\"\n #cropperCardImage\n [buttonLabel]=\"assets()?.image?.url ? 'Cambiar imagen' : 'Cargar una imagen'\"\n [imgStorageSettings]=\"imageStorageSettings()\"\n [currentStorage]=\"assets()?.image\"\n (imageUploaded)=\"onImageUploaded($event, 'image')\"\n (onFileSelected)=\"onFileSelected.emit($event)\"></dc-cropper-modal>\n </div>\n\n <dc-simple-uploader\n [buttonLabel]=\"'Agregar movimiento'\"\n (fileUploaded)=\"onMotionUploaded($event)\"\n [storagePath]=\"storagePath() + '/movimientos/file'\"\n [accept]=\"'video/*'\"></dc-simple-uploader>\n\n <dc-cropper-modal\n #cropperBanner\n id=\"cropperBanner\"\n [buttonLabel]=\"assets()?.banner?.url ? 'Cambiar el banner' : 'Cargar un banner'\"\n [imgStorageSettings]=\"bannerImgSettings()\"\n [currentStorage]=\"assets()?.banner\"\n (imageUploaded)=\"onImageUploaded($event, 'banner')\"></dc-cropper-modal>\n\n <dc-cropper-modal\n id=\"cropperStickers\"\n #cropperStickers\n [buttonLabel]=\"'agregar sticker'\"\n [imgStorageSettings]=\"stickerStorageSettings()\"\n (imageUploaded)=\"onImageUploaded($event, 'sticker')\"></dc-cropper-modal>\n </div>\n </p-message>\n <!-- Banner -->\n\n <div class=\"preview-container\">\n <img [src]=\"assets()?.banner?.url || 'assets/defaults/images/default_banner.webp'\" class=\"main-banner-image-card\" />\n <img [src]=\"assets()?.image?.url || 'assets/defaults/images/default_2_3.webp'\" class=\"main-image-card\" />\n <video class=\"main-motion-card\" [src]=\"assets()?.motion?.url\" autoplay loop muted playsinline></video>\n </div>\n\n <div class=\"stickers-container\">\n @for (sticker of assets()?.stickers; track sticker.url) {\n <div class=\"sticker-wrapper\">\n <img width=\"100\" [src]=\"sticker.url\" alt=\"\" />\n <p-button (click)=\"removeSticker(sticker)\" class=\"remove-sticker\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" />\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".main-image-card{max-width:220px;display:block;border-radius:8px;position:absolute;bottom:-100px;right:20px;transform:none;z-index:1;box-shadow:0 4px 8px #0003}@media (max-width: 1300px){.main-image-card{max-width:170px}}@media (max-width: 768px){.main-image-card{max-width:130px}}.main-motion-card{max-width:220px;display:block;border-radius:8px;position:absolute;bottom:-100px;left:20px;transform:none;z-index:1;box-shadow:0 4px 8px #0003}@media (max-width: 1300px){.main-motion-card{max-width:170px}}@media (max-width: 768px){.main-motion-card{max-width:130px}}.main-banner-image-card{display:block;width:100%;max-height:400px;object-fit:cover;border-radius:8px}.remove-sticker{position:absolute;top:5px;right:5px}.assets-container{position:relative;min-height:60px}.assets-card{border:1px dashed rgba(12,19,142,.1215686275);padding:4px;border-radius:15px}.upload-buttons{display:flex;gap:10px}.preview-container{position:relative;margin-bottom:100px}.stickers-container{display:flex;flex-wrap:wrap;gap:10px}.sticker-wrapper{position:relative}\n"] }]
1032
+ args: [{ selector: 'assets-loader', standalone: true, imports: [CommonModule, CropperComponentModal, SimpleUploaderComponent, ButtonModule, MessageModule, TagModule], template: "<div class=\"assets-container\">\n <div class=\"assets-card\">\n <p-message severity=\"info\">\n <div class=\"upload-buttons\">\n <div>\n <dc-cropper-modal\n id=\"cropperCardImage\"\n #cropperCardImage\n [buttonLabel]=\"assets()?.image?.url ? 'Cambiar imagen' : 'Cargar una imagen'\"\n [imgStorageSettings]=\"imageStorageSettings()\"\n [currentStorage]=\"assets()?.image\"\n (imageUploaded)=\"onImageUploaded($event, 'image')\"\n (onFileSelected)=\"onFileSelected.emit($event)\"></dc-cropper-modal>\n </div>\n\n <dc-simple-uploader\n [buttonLabel]=\"assets()?.motion?.url ? 'Cambiar video principal' : 'Agregar video principal'\"\n (fileUploaded)=\"onMotionUploaded($event)\"\n [storagePath]=\"storagePath() + '/motions/file'\"\n [accept]=\"'video/*'\"></dc-simple-uploader>\n\n <dc-simple-uploader\n [buttonLabel]=\"'Agregar Movimientos'\"\n (fileUploaded)=\"onMotionAdded($event)\"\n [storagePath]=\"storagePath() + '/motions/file'\"\n [accept]=\"'video/*'\"></dc-simple-uploader>\n\n <dc-cropper-modal\n #cropperBanner\n id=\"cropperBanner\"\n [buttonLabel]=\"assets()?.banner?.url ? 'Cambiar el banner' : 'Cargar un banner'\"\n [imgStorageSettings]=\"bannerImgSettings()\"\n [currentStorage]=\"assets()?.banner\"\n (imageUploaded)=\"onImageUploaded($event, 'banner')\"></dc-cropper-modal>\n\n <dc-cropper-modal\n id=\"cropperStickers\"\n #cropperStickers\n [buttonLabel]=\"'Agregar sticker'\"\n [imgStorageSettings]=\"stickerStorageSettings()\"\n (imageUploaded)=\"onImageUploaded($event, 'sticker')\"></dc-cropper-modal>\n </div>\n </p-message>\n <!-- Banner -->\n\n <div class=\"preview-container\">\n <img [src]=\"assets()?.banner?.url || 'assets/defaults/images/default_banner.webp'\" class=\"main-banner-image-card\" />\n <div class=\"main-image-card\">\n <img [src]=\"assets()?.image?.url || 'assets/defaults/images/default_2_3.webp'\" />\n </div>\n\n <div class=\"motion-container\">\n <video #videoPlayer class=\"main-motion-card\" [src]=\"assets()?.motion?.url\" (ended)=\"onVideoEnded(videoPlayer)\" autoplay muted playsinline></video>\n @if(assets()?.motion?.url){\n <p-button class=\"remove-main-motion-button\" (click)=\"removeMainMotion()\" [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-trash\" severity=\"danger\"></p-button>\n }\n </div>\n </div>\n\n <div class=\"stickers-container\">\n @for (sticker of assets()?.stickers; track sticker.url) {\n <div class=\"sticker-wrapper\">\n <img width=\"100\" [src]=\"sticker.url\" alt=\"\" />\n <p-button (click)=\"removeSticker(sticker)\" class=\"remove-sticker\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" />\n </div>\n }\n </div>\n\n <div class=\"motions-container\">\n @for (motion of assets()?.motions; track motion.url) {\n <div class=\"motion-wrapper\">\n <video width=\"150\" [src]=\"motion.url\" controls playsinline preload=\"none\"></video>\n <p-button (click)=\"removeMotion(motion)\" class=\"remove-motion-button\" icon=\"pi pi-trash\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\"></p-button>\n @if(motion.metadata?.moodState){\n <p-tag style=\"position: absolute; top: 4px; left: 4px\" severity=\"secondary\" [value]=\"motion.metadata?.moodState\" />\n } @if(motion.metadata?.event){\n <p-tag style=\"position: absolute; top: 4px; left: 4px\" severity=\"warn\" [value]=\"motion.metadata?.event\" />\n }\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".main-image-card{max-width:220px;display:block;border-radius:8px;position:absolute;bottom:-100px;left:20px;transform:none;z-index:1;box-shadow:0 4px 8px #0003;overflow:hidden}@media (max-width: 1300px){.main-image-card{max-width:170px}}@media (max-width: 768px){.main-image-card{max-width:130px}}.main-motion-card{max-width:100%;display:block;border-radius:8px}.main-banner-image-card{display:block;width:100%;max-height:400px;object-fit:cover;border-radius:8px}.remove-sticker{position:absolute;top:5px;right:5px}.assets-container{position:relative;min-height:60px}.assets-card{border:1px dashed rgba(12,19,142,.1215686275);padding:4px;border-radius:15px}.upload-buttons{display:flex;gap:10px}.preview-container{position:relative;margin-bottom:100px}.stickers-container{display:flex;flex-wrap:wrap;gap:10px}.sticker-wrapper{position:relative}.motion-container{position:absolute;bottom:-100px;right:20px;z-index:1;box-shadow:0 4px 8px #0003;max-width:220px;border-radius:8px;overflow:hidden}@media (max-width: 1300px){.motion-container{max-width:170px}}@media (max-width: 768px){.motion-container{max-width:130px}}.remove-main-motion-button{position:absolute;top:10px;right:10px;z-index:2}.motions-container{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px}.motion-wrapper{position:relative;width:150px;border-radius:8px;overflow:hidden;box-shadow:0 2px 4px #0000001a}.motion-wrapper video{min-height:220px;display:block;background-color:#f0f0f0}.remove-motion-button{position:absolute;top:5px;right:5px;z-index:2}\n"] }]
777
1033
  }] });
778
1034
 
779
1035
  /*
@@ -784,5 +1040,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
784
1040
  * Generated bundle index. Do not edit.
785
1041
  */
786
1042
 
787
- export { AspectRatio, AspectRatio2, AspectRatioOptions, AspectType, CropperComponent, CropperComponentModal, CsaAssetsLoaderComponent, DCFilesCacheService, DEFAULT_SETTINGS, ImageStoragePreviewComponent, MultiImagesStorageService, MultiObjectStorageService, ResolutionType, SimpleUploaderComponent, extractBucket, extractPath };
1043
+ export { AspectRatio, AspectRatio2, AspectRatioOptions, AspectType, AssetsLoaderComponent, CropperComponent, CropperComponentModal, DCFilesCacheService, DEFAULT_SETTINGS, ImageStoragePreviewComponent, MultiImagesStorageService, MultiObjectStorageService, ResolutionType, SafeHtmlPipe, SimpleUploaderComponent, extractBucket, extractPath };
788
1044
  //# sourceMappingURL=dataclouder-ngx-cloud-storage.mjs.map