@bebranded/bb-contents 1.0.28-beta → 1.0.30-beta

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.
Files changed (2) hide show
  1. package/bb-contents.js +158 -10
  2. package/package.json +1 -1
package/bb-contents.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * BeBranded Contents
3
3
  * Contenus additionnels français pour Webflow
4
- * @version 1.0.28-beta
4
+ * @version 1.0.30-beta
5
5
  * @author BeBranded
6
6
  * @license MIT
7
7
  * @website https://www.bebranded.xyz
@@ -17,7 +17,7 @@
17
17
 
18
18
  // Configuration
19
19
  const config = {
20
- version: '1.0.28-beta',
20
+ version: '1.0.30-beta',
21
21
  debug: window.location.hostname === 'localhost' || window.location.hostname.includes('webflow.io'),
22
22
  prefix: 'bb-', // utilisé pour générer les sélecteurs (data-bb-*)
23
23
  i18n: {
@@ -526,11 +526,69 @@
526
526
 
527
527
  // Module YouTube Feed
528
528
  youtube: {
529
+ // Détection des bots pour éviter les appels API inutiles
530
+ isBot: function() {
531
+ const userAgent = navigator.userAgent.toLowerCase();
532
+ const botPatterns = [
533
+ 'bot', 'crawler', 'spider', 'scraper', 'googlebot', 'bingbot', 'slurp',
534
+ 'duckduckbot', 'baiduspider', 'yandexbot', 'facebookexternalhit', 'twitterbot',
535
+ 'linkedinbot', 'whatsapp', 'telegrambot', 'discordbot', 'slackbot'
536
+ ];
537
+
538
+ return botPatterns.some(pattern => userAgent.includes(pattern)) ||
539
+ navigator.webdriver ||
540
+ !navigator.userAgent;
541
+ },
542
+
543
+ // Gestion du cache localStorage
544
+ cache: {
545
+ get: function(key) {
546
+ try {
547
+ const cached = localStorage.getItem(key);
548
+ if (!cached) return null;
549
+
550
+ const data = JSON.parse(cached);
551
+ const now = Date.now();
552
+
553
+ // Cache expiré après 24h
554
+ if (now - data.timestamp > 24 * 60 * 60 * 1000) {
555
+ localStorage.removeItem(key);
556
+ return null;
557
+ }
558
+
559
+ return data.value;
560
+ } catch (e) {
561
+ return null;
562
+ }
563
+ },
564
+
565
+ set: function(key, value) {
566
+ try {
567
+ const data = {
568
+ value: value,
569
+ timestamp: Date.now()
570
+ };
571
+ localStorage.setItem(key, JSON.stringify(data));
572
+ } catch (e) {
573
+ // Ignorer les erreurs de localStorage
574
+ }
575
+ }
576
+ },
577
+
529
578
  detect: function(scope) {
530
579
  return scope.querySelector('[bb-youtube-channel]') !== null;
531
580
  },
532
581
 
533
582
  init: function(scope) {
583
+ // Vérifier si c'est un bot - pas d'appel API
584
+ if (this.isBot()) {
585
+ bbContents.utils.log('Bot détecté, pas de chargement YouTube (économie API)');
586
+ return;
587
+ }
588
+
589
+ // Nettoyer le cache expiré au démarrage
590
+ this.cleanCache();
591
+
534
592
  const elements = scope.querySelectorAll('[bb-youtube-channel]');
535
593
  if (elements.length === 0) return;
536
594
 
@@ -585,6 +643,16 @@
585
643
  // Marquer l'élément comme traité par le module YouTube
586
644
  element.setAttribute('data-bb-youtube-processed', 'true');
587
645
 
646
+ // Vérifier le cache d'abord
647
+ const cacheKey = `youtube_${channelId}_${videoCount}_${allowShorts}`;
648
+ const cachedData = this.cache.get(cacheKey);
649
+
650
+ if (cachedData) {
651
+ bbContents.utils.log('Données YouTube récupérées du cache (économie API)');
652
+ this.generateYouTubeFeed(container, template, cachedData, allowShorts);
653
+ return;
654
+ }
655
+
588
656
  // Afficher un loader
589
657
  container.innerHTML = '<div style="padding: 20px; text-align: center; color: #6b7280;">Chargement des vidéos YouTube...</div>';
590
658
 
@@ -600,10 +668,29 @@
600
668
  if (data.error) {
601
669
  throw new Error(data.error.message || 'Erreur API YouTube');
602
670
  }
671
+
672
+ // Sauvegarder en cache pour 24h
673
+ this.cache.set(cacheKey, data);
674
+ bbContents.utils.log('Données YouTube mises en cache pour 24h (économie API)');
675
+
603
676
  this.generateYouTubeFeed(container, template, data, allowShorts);
604
677
  })
605
678
  .catch(error => {
606
679
  bbContents.utils.log('Erreur dans le module youtube:', error);
680
+
681
+ // En cas d'erreur, essayer de récupérer du cache même expiré
682
+ const expiredCache = localStorage.getItem(cacheKey);
683
+ if (expiredCache) {
684
+ try {
685
+ const cachedData = JSON.parse(expiredCache);
686
+ bbContents.utils.log('Utilisation du cache expiré en cas d\'erreur API');
687
+ this.generateYouTubeFeed(container, template, cachedData.value, allowShorts);
688
+ return;
689
+ } catch (e) {
690
+ // Ignorer les erreurs de parsing
691
+ }
692
+ }
693
+
607
694
  container.innerHTML = `<div style="padding: 20px; background: #fef2f2; border: 1px solid #fecaca; border-radius: 8px; color: #dc2626;"><strong>Erreur de chargement</strong><br>${error.message}</div>`;
608
695
  });
609
696
  });
@@ -655,16 +742,46 @@
655
742
  element.rel = 'noopener noreferrer';
656
743
  }
657
744
 
658
- // Remplir la thumbnail (haute qualité)
745
+ // Remplir la thumbnail (qualité optimisée)
659
746
  const thumbnail = element.querySelector('[bb-youtube-thumbnail]');
660
747
  if (thumbnail) {
661
- // Utiliser la meilleure qualité disponible
662
- const highQualityUrl = snippet.thumbnails.maxres?.url ||
663
- snippet.thumbnails.high?.url ||
664
- snippet.thumbnails.medium?.url ||
665
- snippet.thumbnails.default?.url;
666
- thumbnail.src = highQualityUrl;
667
- thumbnail.alt = snippet.title;
748
+ // Logique optimisée pour la meilleure qualité disponible
749
+ let bestThumbnailUrl = null;
750
+ let bestQuality = 'unknown';
751
+
752
+ // Priorité 1: maxres (1280x720) - qualité maximale
753
+ if (snippet.thumbnails.maxres?.url) {
754
+ bestThumbnailUrl = snippet.thumbnails.maxres.url;
755
+ bestQuality = 'maxres (1280x720)';
756
+ }
757
+ // Priorité 2: high (480x360) - bonne qualité pour l'affichage
758
+ else if (snippet.thumbnails.high?.url) {
759
+ bestThumbnailUrl = snippet.thumbnails.high.url;
760
+ bestQuality = 'high (480x360)';
761
+ }
762
+ // Priorité 3: medium (320x180) - qualité acceptable en dernier recours
763
+ else if (snippet.thumbnails.medium?.url) {
764
+ bestThumbnailUrl = snippet.thumbnails.medium.url;
765
+ bestQuality = 'medium (320x180)';
766
+ }
767
+ // Fallback: default (120x90) - seulement si rien d'autre
768
+ else if (snippet.thumbnails.default?.url) {
769
+ bestThumbnailUrl = snippet.thumbnails.default.url;
770
+ bestQuality = 'default (120x90)';
771
+ }
772
+
773
+ // Appliquer la meilleure thumbnail trouvée
774
+ if (bestThumbnailUrl) {
775
+ thumbnail.src = bestThumbnailUrl;
776
+ thumbnail.alt = snippet.title;
777
+
778
+ // Debug: logger la qualité utilisée (en mode debug seulement)
779
+ if (bbContents.config.debug) {
780
+ bbContents.utils.log(`Thumbnail optimisée pour ${snippet.title}: ${bestQuality}`);
781
+ }
782
+ } else {
783
+ bbContents.utils.log('Aucune thumbnail disponible pour:', snippet.title);
784
+ }
668
785
  }
669
786
 
670
787
  // Remplir le titre (avec décodage HTML)
@@ -711,6 +828,37 @@
711
828
  const textarea = document.createElement('textarea');
712
829
  textarea.innerHTML = text;
713
830
  return textarea.value;
831
+ },
832
+
833
+ // Nettoyer le cache expiré
834
+ cleanCache: function() {
835
+ try {
836
+ const keys = Object.keys(localStorage);
837
+ const now = Date.now();
838
+ let cleaned = 0;
839
+
840
+ keys.forEach(key => {
841
+ if (key.startsWith('youtube_')) {
842
+ try {
843
+ const cached = JSON.parse(localStorage.getItem(key));
844
+ if (now - cached.timestamp > 24 * 60 * 60 * 1000) {
845
+ localStorage.removeItem(key);
846
+ cleaned++;
847
+ }
848
+ } catch (e) {
849
+ // Supprimer les clés corrompues
850
+ localStorage.removeItem(key);
851
+ cleaned++;
852
+ }
853
+ }
854
+ });
855
+
856
+ if (cleaned > 0) {
857
+ bbContents.utils.log(`Cache YouTube nettoyé: ${cleaned} entrées supprimées`);
858
+ }
859
+ } catch (e) {
860
+ // Ignorer les erreurs de nettoyage
861
+ }
714
862
  }
715
863
  }
716
864
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bebranded/bb-contents",
3
- "version": "1.0.28-beta",
3
+ "version": "1.0.30-beta",
4
4
  "description": "Contenus additionnels français pour Webflow",
5
5
  "main": "bb-contents.js",
6
6
  "scripts": {