zen-wdg 2.2.7 → 2.3.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.
@@ -32,10 +32,10 @@
32
32
  class="logo-container"
33
33
  >
34
34
  <img
35
- :src="item.logo"
35
+ :src="getFaviconUrl(item)"
36
36
  :alt="item.title + ' logo'"
37
37
  :class="{ small: small }"
38
- @error="onImageError($event, item.title)"
38
+ @error="onImageError($event, item)"
39
39
  />
40
40
  </div>
41
41
  {{ item.title }}
@@ -89,71 +89,71 @@ export default {
89
89
  {
90
90
  title: 'Astian',
91
91
  url: 'https://astian.org/',
92
- logo: 'https://www.google.com/s2/favicons?domain=astian.org&sz=64'
92
+ domain: 'astian.org'
93
93
  },
94
94
  {
95
95
  title: 'Amazon',
96
96
  url: 'https://r.v2i8b.com/api/v1/bid/redirect?campaign_id=01JVSM9HD56Q0VD2QZXQ2AR505&url=https%3A%2F%2Famazon.com',
97
- logo: 'https://www.google.com/s2/favicons?domain=amazon.com&sz=64'
97
+ domain: 'amazon.com'
98
98
  },
99
99
  {
100
100
  title: 'Avast',
101
101
  url: 'https://r.v2i8b.com/api/v1/bid/redirect?campaign_id=01JVSM8H9350F4CBP07A8V7C5T&url=http%3A%2F%2Favast.com%2F',
102
- logo: 'https://www.google.com/s2/favicons?domain=avast.com&sz=64'
102
+ domain: 'avast.com'
103
103
  },
104
104
  {
105
105
  title: 'Youtube',
106
106
  url: 'https://youtube.com',
107
- logo: 'https://www.google.com/s2/favicons?domain=youtube.com&sz=64'
107
+ domain: 'youtube.com'
108
108
  },
109
109
  {
110
110
  title: 'Instagram',
111
111
  url: 'https://instagram.com',
112
- logo: 'https://www.google.com/s2/favicons?domain=instagram.com&sz=64'
112
+ domain: 'instagram.com'
113
113
  },
114
114
  {
115
115
  title: 'Wish.com',
116
116
  url: 'https://r.v2i8b.com/api/v1/bid/redirect?campaign_id=01JVSM8H9350F4CBP07A8V7C5T&url=http%3A%2F%2Fwish.com',
117
- logo: 'https://www.google.com/s2/favicons?domain=wish.com&sz=64'
117
+ domain: 'wish.com'
118
118
  },
119
119
  {
120
120
  title: 'Prime',
121
121
  url: 'https://r.v2i8b.com/api/v1/bid/redirect?campaign_id=01JVSM8H9350F4CBP07A8V7C5T&url=http%3A%2F%2Fprimevideo.com',
122
- logo: 'https://www.google.com/s2/favicons?domain=primevideo.com&sz=64'
122
+ domain: 'primevideo.com'
123
123
  },
124
124
  {
125
125
  title: 'Shein',
126
126
  url: 'https://r.v2i8b.com/api/v1/bid/redirect?campaign_id=01JVSM8H9350F4CBP07A8V7C5T&url=http%3A%2F%2Fshein.com',
127
- logo: 'https://www.google.com/s2/favicons?domain=shein.com&sz=64'
127
+ domain: 'shein.com'
128
128
  }
129
129
  ],
130
130
  Work: [
131
131
  {
132
132
  title: 'GitHub',
133
133
  url: 'https://github.com',
134
- logo: 'https://www.google.com/s2/favicons?domain=github.com&sz=64'
134
+ domain: 'github.com'
135
135
  },
136
136
  {
137
137
  title: 'Notion',
138
138
  url: 'https://notion.so',
139
- logo: 'https://www.google.com/s2/favicons?domain=notion.so&sz=64'
139
+ domain: 'notion.so'
140
140
  }
141
141
  ],
142
142
  Study: [
143
143
  {
144
144
  title: 'MDN Web Docs',
145
145
  url: 'https://developer.mozilla.org',
146
- logo: 'https://www.google.com/s2/favicons?domain=mozilla.org&sz=64'
146
+ domain: 'mozilla.org'
147
147
  },
148
148
  {
149
149
  title: 'FreeCodeCamp',
150
150
  url: 'https://freecodecamp.org',
151
- logo: 'https://www.google.com/s2/favicons?domain=freecodecamp.org&sz=64'
151
+ domain: 'freecodecamp.org'
152
152
  },
153
153
  {
154
154
  title: 'Udemy',
155
155
  url: 'https://r.v2i8b.com/api/v1/bid/redirect?campaign_id=01JVSM8H9350F4CBP07A8V7C5T&url=http%3A%2F%2Fudemy.com%2F',
156
- logo: 'https://www.google.com/s2/favicons?domain=udemy.com&sz=64'
156
+ domain: 'udemy.com'
157
157
  }
158
158
  ]
159
159
  };
@@ -165,7 +165,8 @@ export default {
165
165
  return {
166
166
  STORAGE_KEY,
167
167
  bookmarks,
168
- activeTab: 'Personal'
168
+ activeTab: 'Personal',
169
+ faviconAttempts: {}
169
170
  };
170
171
  },
171
172
  computed: {
@@ -189,39 +190,127 @@ export default {
189
190
  window.open(url, '_blank');
190
191
  }
191
192
  },
192
- deleteBookmark(index) {
193
+ async deleteBookmark(index) {
193
194
  const item = this.bookmarks[this.activeTab][index];
194
- if (confirm(`¿Estás seguro de eliminar ${item.title}?`)) {
195
+ const confirmed = await window.ZenModals.showDeleteConfirm(item.title);
196
+ if (confirmed) {
195
197
  this.bookmarks[this.activeTab].splice(index, 1);
196
198
  this.saveState();
197
199
  }
198
200
  },
199
- editBookmark(index) {
201
+ async editBookmark(index) {
200
202
  const item = this.bookmarks[this.activeTab][index];
201
- const newTitle = prompt('Nuevo título:', item.title);
202
- if (newTitle === null) return;
203
- const newUrl = prompt('Nueva URL:', item.url);
204
- if (newUrl === null) return;
205
- item.title = newTitle;
206
- item.url = newUrl;
207
- item.logo = `https://www.google.com/s2/favicons?domain=${new URL(newUrl).hostname}&sz=64`;
208
- this.saveState();
203
+
204
+ const newTitle = await window.ZenModals.showPrompt({
205
+ title: 'Editar Marcador',
206
+ message: 'Introduce el nuevo título:',
207
+ inputDefaultValue: item.title,
208
+ inputPlaceholder: 'Título del marcador'
209
+ });
210
+
211
+ if (!newTitle) return;
212
+
213
+ const newUrl = await window.ZenModals.showPrompt({
214
+ title: 'Editar URL',
215
+ message: 'Introduce la nueva URL:',
216
+ inputDefaultValue: item.url,
217
+ inputType: 'url',
218
+ inputPlaceholder: 'https://ejemplo.com'
219
+ });
220
+
221
+ if (!newUrl) return;
222
+
223
+ try {
224
+ item.title = newTitle;
225
+ item.url = newUrl;
226
+ item.domain = new URL(newUrl).hostname;
227
+ delete item.logo; // Limpiar logo antiguo para regeneración
228
+ this.saveState();
229
+ } catch (error) {
230
+ console.error('URL inválida:', error);
231
+ }
209
232
  },
210
- addBookmarkPrompt() {
211
- const title = prompt('Nombre del marcador:');
233
+ async addBookmarkPrompt() {
234
+ const title = await window.ZenModals.showPrompt({
235
+ title: 'Nuevo Marcador',
236
+ message: 'Introduce el nombre del marcador:',
237
+ inputPlaceholder: 'Nombre del sitio'
238
+ });
239
+
212
240
  if (!title) return;
213
- const url = prompt('URL del marcador:');
241
+
242
+ const url = await window.ZenModals.showPrompt({
243
+ title: 'URL del Marcador',
244
+ message: 'Introduce la URL:',
245
+ inputType: 'url',
246
+ inputPlaceholder: 'https://ejemplo.com'
247
+ });
248
+
214
249
  if (!url) return;
215
- const logo = `https://www.google.com/s2/favicons?domain=${new URL(url).hostname}&sz=64`;
216
- this.bookmarks[this.activeTab].push({ title, url, logo });
217
- this.saveState();
250
+
251
+ try {
252
+ const domain = new URL(url).hostname;
253
+ this.bookmarks[this.activeTab].push({ title, url, domain });
254
+ this.saveState();
255
+ } catch (error) {
256
+ console.error('URL inválida:', error);
257
+ }
258
+ },
259
+ getFaviconUrl(item) {
260
+ // Si ya existe logo guardado, usarlo
261
+ if (item.logo) return item.logo;
262
+
263
+ const domain = item.domain || this.extractDomain(item.url);
264
+ const attempt = this.faviconAttempts[domain] || 0;
265
+
266
+ // Lista de servicios de favicon en orden de prioridad
267
+ const services = [
268
+ `https://icons.duckduckgo.com/ip3/${domain}.ico`,
269
+ `https://www.google.com/s2/favicons?domain=${domain}&sz=128`,
270
+ `https://logo.clearbit.com/${domain}`,
271
+ `https://favicons.githubusercontent.com/${domain}`,
272
+ `https://${domain}/favicon.ico`
273
+ ];
274
+
275
+ return services[Math.min(attempt, services.length - 1)];
218
276
  },
219
- onImageError(event, title) {
277
+
278
+ extractDomain(url) {
279
+ try {
280
+ return new URL(url).hostname;
281
+ } catch {
282
+ return url;
283
+ }
284
+ },
285
+
286
+ onImageError(event, item) {
220
287
  const img = event.target;
221
- img.style.display = 'none';
222
- const iconContainer = img.parentNode;
223
- iconContainer.style.backgroundColor = '#066D5A';
224
- iconContainer.textContent = title.charAt(0).toUpperCase();
288
+ const domain = item.domain || this.extractDomain(item.url);
289
+ const currentAttempt = this.faviconAttempts[domain] || 0;
290
+
291
+ // Máximo 5 intentos (todos los servicios)
292
+ if (currentAttempt < 4) {
293
+ // Intentar siguiente servicio
294
+ this.faviconAttempts[domain] = currentAttempt + 1;
295
+ img.src = this.getFaviconUrl(item);
296
+ } else {
297
+ // Fallback final: mostrar letra inicial
298
+ img.style.display = 'none';
299
+ const iconContainer = img.parentNode;
300
+
301
+ // Generar color basado en el título
302
+ const colors = ['#066D5A', '#0891b2', '#7c3aed', '#dc2626', '#ea580c', '#ca8a04', '#16a34a'];
303
+ const colorIndex = item.title.charCodeAt(0) % colors.length;
304
+
305
+ iconContainer.style.backgroundColor = colors[colorIndex];
306
+ iconContainer.style.display = 'flex';
307
+ iconContainer.style.alignItems = 'center';
308
+ iconContainer.style.justifyContent = 'center';
309
+ iconContainer.style.fontSize = '1.5rem';
310
+ iconContainer.style.fontWeight = 'bold';
311
+ iconContainer.style.color = 'white';
312
+ iconContainer.textContent = item.title.charAt(0).toUpperCase();
313
+ }
225
314
  }
226
315
  },
227
316
  watch: {
@@ -375,12 +464,28 @@ export default {
375
464
  font-size: 1rem;
376
465
  }
377
466
 
467
+ .logo-container {
468
+ width: 50px;
469
+ height: 50px;
470
+ border-radius: 0.4rem;
471
+ overflow: hidden;
472
+ display: flex;
473
+ align-items: center;
474
+ justify-content: center;
475
+ }
476
+
477
+ .card.small .logo-container {
478
+ width: 55px;
479
+ height: 55px;
480
+ }
481
+
378
482
  .card-link img {
379
483
  width: 100%;
380
484
  max-width: 50px;
381
485
  height: 100%;
382
486
  height: 50px;
383
487
  border-radius: 0.4rem;
488
+ object-fit: cover;
384
489
  }
385
490
 
386
491
  .card-link img.small {