@jjlmoya/utils-audiovisual 1.4.0 → 1.6.0

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,6 +1,5 @@
1
1
  ---
2
2
  import type { ExifCleanerUI } from './index';
3
- import './style.css';
4
3
 
5
4
  interface Props {
6
5
  ui: ExifCleanerUI;
@@ -74,24 +73,24 @@ const { ui } = Astro.props;
74
73
  import { extractExif, createCleanImage } from './logic';
75
74
  import type { ExifCleanerUI } from './index';
76
75
 
77
- function renderMetadata(tags: Record<string, string | number | boolean | undefined>, container: HTMLElement, riskTitle: string) {
78
- const keys = Object.keys(tags);
79
- if (keys.length === 0) {
80
- container.innerHTML = '<div class="ec-no-metadata">No se encontraron metadatos.</div>';
81
- return;
82
- }
83
- let html = `<div class="ec-metadata-title">${riskTitle}</div><ul class="ec-metadata-list">`;
84
- if (tags.GPSLocation) html += `<li><span>GPS:</span> <span>${tags.GPSLocation}</span></li>`;
85
- if (tags.Model) html += `<li><span>CÁMARA:</span> <span>${tags.Model}</span></li>`;
86
- if (tags.DateTimeOriginal) html += `<li><span>FECHA:</span> <span>${tags.DateTimeOriginal}</span></li>`;
87
- container.innerHTML = html + '</ul>';
88
- }
89
-
90
76
  function init() {
91
77
  const root = document.getElementById('ec-root');
92
78
  if (!root) return;
93
79
 
94
80
  const ui = JSON.parse(root.dataset.ui ?? '{}') as ExifCleanerUI;
81
+
82
+ function renderMetadata(tags: Record<string, string | number | boolean | undefined>, container: HTMLElement, riskTitle: string) {
83
+ const keys = Object.keys(tags);
84
+ if (keys.length === 0) {
85
+ container.innerHTML = `<div class="ec-no-metadata">${ui.noMetadataFound}</div>`;
86
+ return;
87
+ }
88
+ let html = `<div class="ec-metadata-title">${riskTitle}</div><ul class="ec-metadata-list">`;
89
+ if (tags.GPSLocation) html += `<li><span>${ui.gpsLabel}</span> <span>${tags.GPSLocation}</span></li>`;
90
+ if (tags.Model) html += `<li><span>${ui.cameraLabel}</span> <span>${tags.Model}</span></li>`;
91
+ if (tags.DateTimeOriginal) html += `<li><span>${ui.dateLabel}</span> <span>${tags.DateTimeOriginal}</span></li>`;
92
+ container.innerHTML = html + '</ul>';
93
+ }
95
94
  const initial = root.querySelector('#ec-initial') as HTMLElement;
96
95
  const processing = root.querySelector('#ec-processing') as HTMLElement;
97
96
  const result = root.querySelector('#ec-result') as HTMLElement;
@@ -115,6 +114,7 @@ const { ui } = Astro.props;
115
114
  const blob = await createCleanImage(img);
116
115
 
117
116
  downloadBtn.onclick = () => {
117
+ if (!blob) return;
118
118
  const url = URL.createObjectURL(blob);
119
119
  const a = document.createElement('a');
120
120
  a.href = url;
@@ -160,3 +160,295 @@ const { ui } = Astro.props;
160
160
  init();
161
161
  document.addEventListener('astro:page-load', init);
162
162
  </script>
163
+
164
+ <style>
165
+ :global(.ec-root) {
166
+ --ec-bg: #fff;
167
+ --ec-bg-elevated: #f8fafc;
168
+ --ec-border: #e2e8f0;
169
+ --ec-text: #0f172a;
170
+ --ec-text-muted: #64748b;
171
+ --ec-accent: #6366f1;
172
+ --ec-accent-alpha: rgba(99, 102, 241, 0.08);
173
+ --ec-accent-alpha-hover: rgba(99, 102, 241, 0.02);
174
+ --ec-shadow: rgba(0, 0, 0, 0.15);
175
+
176
+ padding: 2.5rem 1.5rem;
177
+ max-width: 1000px;
178
+ margin: 0 auto;
179
+ }
180
+
181
+ :global(.theme-dark .ec-root) {
182
+ --ec-bg: #18181b;
183
+ --ec-bg-elevated: #27272a;
184
+ --ec-border: #3f3f46;
185
+ --ec-text: #f4f4f5;
186
+ --ec-text-muted: #71717a;
187
+ --ec-accent: #818cf8;
188
+ --ec-accent-alpha: rgba(129, 140, 248, 0.12);
189
+ --ec-accent-alpha-hover: rgba(129, 140, 248, 0.02);
190
+ --ec-shadow: rgba(0, 0, 0, 0.3);
191
+ }
192
+
193
+ :global(.ec-card) {
194
+ background: var(--ec-bg);
195
+ border: 1px solid var(--ec-border);
196
+ border-radius: 3rem;
197
+ padding: 1.5rem;
198
+ box-shadow: 0 45px 120px -30px var(--ec-shadow);
199
+ position: relative;
200
+ overflow: hidden;
201
+ }
202
+
203
+ :global(.ec-drop) {
204
+ padding: 4rem 2rem;
205
+ border: 3px dashed var(--ec-border);
206
+ border-radius: 2.5rem;
207
+ display: flex;
208
+ flex-direction: column;
209
+ align-items: center;
210
+ text-align: center;
211
+ cursor: pointer;
212
+ gap: 1.5rem;
213
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
214
+ }
215
+
216
+ :global(.ec-drop:hover),
217
+ :global(.ec-drop-active) {
218
+ border-color: var(--ec-accent);
219
+ background: var(--ec-accent-alpha-hover);
220
+ }
221
+
222
+ :global(.ec-drop-icon) {
223
+ width: 6rem;
224
+ height: 6rem;
225
+ background: var(--ec-accent-alpha);
226
+ border-radius: 2rem;
227
+ display: flex;
228
+ align-items: center;
229
+ justify-content: center;
230
+ color: var(--ec-accent);
231
+ }
232
+
233
+ :global(.ec-drop-icon svg) {
234
+ width: 3rem;
235
+ height: 3rem;
236
+ }
237
+
238
+ :global(.ec-title) {
239
+ font-size: 2.5rem;
240
+ font-weight: 950;
241
+ color: var(--ec-text);
242
+ margin: 0;
243
+ }
244
+
245
+ :global(.ec-subtitle) {
246
+ font-size: 1.15rem;
247
+ color: var(--ec-text-muted);
248
+ max-width: 500px;
249
+ margin: 0;
250
+ font-weight: 700;
251
+ }
252
+
253
+ :global(.ec-badges) {
254
+ display: flex;
255
+ gap: 1rem;
256
+ flex-wrap: wrap;
257
+ justify-content: center;
258
+ }
259
+
260
+ :global(.ec-badge) {
261
+ padding: 0.6rem 1.25rem;
262
+ background: var(--ec-bg-elevated);
263
+ border-radius: 2rem;
264
+ font-size: 0.8rem;
265
+ font-weight: 800;
266
+ color: var(--ec-text-muted);
267
+ display: flex;
268
+ align-items: center;
269
+ gap: 0.5rem;
270
+ }
271
+
272
+ :global(.ec-badge svg) {
273
+ width: 1rem;
274
+ height: 1rem;
275
+ flex-shrink: 0;
276
+ }
277
+
278
+ :global(.ec-processing) {
279
+ padding: 5rem;
280
+ display: flex;
281
+ flex-direction: column;
282
+ align-items: center;
283
+ justify-content: center;
284
+ gap: 1.5rem;
285
+ }
286
+
287
+ :global(.ec-spinner) {
288
+ width: 4rem;
289
+ height: 4rem;
290
+ border: 4px solid var(--ec-accent-alpha);
291
+ border-top-color: var(--ec-accent);
292
+ border-radius: 50%;
293
+ animation: ec-spin 0.8s linear infinite;
294
+ }
295
+
296
+ :global(.ec-processing-text) {
297
+ font-weight: 800;
298
+ color: var(--ec-text);
299
+ margin: 0;
300
+ }
301
+
302
+ :global(.ec-result) {
303
+ padding: 2.5rem;
304
+ display: flex;
305
+ flex-direction: column;
306
+ animation: ec-slide-up 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
307
+ }
308
+
309
+ :global(.ec-result-layout) {
310
+ display: grid;
311
+ grid-template-columns: 1fr 1fr;
312
+ gap: 3rem;
313
+ }
314
+
315
+ @media (max-width: 800px) {
316
+ :global(.ec-result-layout) {
317
+ grid-template-columns: 1fr;
318
+ }
319
+ }
320
+
321
+ :global(.ec-preview-col) {
322
+ display: flex;
323
+ flex-direction: column;
324
+ gap: 1.5rem;
325
+ }
326
+
327
+ :global(.ec-preview-img) {
328
+ width: 100%;
329
+ border-radius: 1.5rem;
330
+ box-shadow: 0 20px 50px var(--ec-shadow);
331
+ display: block;
332
+ }
333
+
334
+ :global(.ec-metadata) {
335
+ background: var(--ec-bg-elevated);
336
+ border: 1px solid var(--ec-border);
337
+ border-radius: 1.25rem;
338
+ padding: 1.5rem;
339
+ min-height: 150px;
340
+ display: flex;
341
+ flex-direction: column;
342
+ justify-content: center;
343
+ }
344
+
345
+ :global(.ec-no-metadata) {
346
+ display: flex;
347
+ align-items: center;
348
+ justify-content: center;
349
+ height: 100%;
350
+ color: var(--ec-text-muted);
351
+ text-align: center;
352
+ }
353
+
354
+ :global(.ec-metadata-title) {
355
+ color: var(--ec-accent);
356
+ font-weight: 700;
357
+ margin-bottom: 1rem;
358
+ font-size: 0.9rem;
359
+ }
360
+
361
+ :global(.ec-metadata-list) {
362
+ list-style: none;
363
+ padding: 0;
364
+ margin: 0;
365
+ display: flex;
366
+ flex-direction: column;
367
+ gap: 0.75rem;
368
+ }
369
+
370
+ :global(.ec-metadata-list li) {
371
+ display: flex;
372
+ justify-content: space-between;
373
+ gap: 1rem;
374
+ font-size: 0.85rem;
375
+ font-weight: 600;
376
+ color: var(--ec-text);
377
+ }
378
+
379
+ :global(.ec-metadata-list li span:first-child) {
380
+ font-weight: 700;
381
+ }
382
+
383
+ :global(.ec-metadata-list li span:last-child) {
384
+ color: var(--ec-text-muted);
385
+ }
386
+
387
+ :global(.ec-actions-col) {
388
+ display: flex;
389
+ flex-direction: column;
390
+ gap: 1.5rem;
391
+ }
392
+
393
+ :global(.ec-btn) {
394
+ padding: 1.25rem;
395
+ border-radius: 1.5rem;
396
+ font-weight: 950;
397
+ font-size: 1.1rem;
398
+ border: none;
399
+ cursor: pointer;
400
+ display: flex;
401
+ align-items: center;
402
+ justify-content: center;
403
+ gap: 0.75rem;
404
+ transition: all 0.2s;
405
+ }
406
+
407
+ :global(.ec-btn svg) {
408
+ width: 1.25rem;
409
+ height: 1.25rem;
410
+ }
411
+
412
+ :global(.ec-btn-primary) {
413
+ background: var(--ec-accent);
414
+ color: #fff;
415
+ box-shadow: 0 15px 35px -10px var(--ec-accent);
416
+ }
417
+
418
+ :global(.ec-btn-primary:hover) {
419
+ transform: translateY(-2px);
420
+ box-shadow: 0 20px 45px -10px var(--ec-accent);
421
+ }
422
+
423
+ :global(.ec-btn-secondary) {
424
+ background: var(--ec-bg-elevated);
425
+ border: 1px solid var(--ec-border);
426
+ color: var(--ec-text);
427
+ }
428
+
429
+ :global(.ec-btn-secondary:hover) {
430
+ border-color: var(--ec-accent);
431
+ color: var(--ec-accent);
432
+ }
433
+
434
+ .ec-hidden {
435
+ display: none;
436
+ }
437
+
438
+ @keyframes ec-spin {
439
+ to {
440
+ transform: rotate(360deg);
441
+ }
442
+ }
443
+
444
+ @keyframes ec-slide-up {
445
+ from {
446
+ opacity: 0;
447
+ transform: translateY(30px);
448
+ }
449
+ to {
450
+ opacity: 1;
451
+ transform: translateY(0);
452
+ }
453
+ }
454
+ </style>