@bebranded/bb-contents 1.0.3-beta → 1.0.5-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.
- package/bb-contents.js +132 -1
- package/package.json +1 -1
package/bb-contents.js
CHANGED
|
@@ -792,7 +792,138 @@
|
|
|
792
792
|
|
|
793
793
|
bbContents.utils.log('Module Marquee initialisé:', elements.length, 'éléments');
|
|
794
794
|
}
|
|
795
|
-
}
|
|
795
|
+
},
|
|
796
|
+
|
|
797
|
+
// Module YouTube Feed
|
|
798
|
+
youtube: {
|
|
799
|
+
init: function() {
|
|
800
|
+
const elements = document.querySelectorAll('[bb-youtube-channel]');
|
|
801
|
+
if (elements.length === 0) return;
|
|
802
|
+
|
|
803
|
+
bbContents.utils.log('Module détecté: youtube');
|
|
804
|
+
|
|
805
|
+
elements.forEach(element => {
|
|
806
|
+
if (element.bbProcessed) return;
|
|
807
|
+
element.bbProcessed = true;
|
|
808
|
+
|
|
809
|
+
const channelId = bbContents._getAttr(element, 'bb-youtube-channel');
|
|
810
|
+
const videoCount = bbContents._getAttr(element, 'bb-youtube-video-count') || '10';
|
|
811
|
+
const endpoint = bbContents.config.youtubeEndpoint;
|
|
812
|
+
|
|
813
|
+
if (!channelId) {
|
|
814
|
+
bbContents.utils.log('Erreur: bb-youtube-channel manquant');
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
if (!endpoint) {
|
|
819
|
+
bbContents.utils.log('Erreur: youtubeEndpoint non configuré. Utilisez bbContents.config.youtubeEndpoint = "votre-worker-url"');
|
|
820
|
+
element.innerHTML = '<div style="padding: 20px; background: #fef2f2; border: 1px solid #fecaca; border-radius: 8px; color: #dc2626;"><strong>Configuration YouTube manquante</strong><br>Ajoutez : bbContents.config.youtubeEndpoint = "votre-worker-url"</div>';
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
// Afficher un loader
|
|
825
|
+
element.innerHTML = '<div style="padding: 20px; text-align: center; color: #6b7280;">Chargement des vidéos YouTube...</div>';
|
|
826
|
+
|
|
827
|
+
// Appeler l'API via le Worker
|
|
828
|
+
fetch(`${endpoint}?channelId=${channelId}&maxResults=${videoCount}`)
|
|
829
|
+
.then(response => {
|
|
830
|
+
if (!response.ok) {
|
|
831
|
+
throw new Error(`HTTP ${response.status}`);
|
|
832
|
+
}
|
|
833
|
+
return response.json();
|
|
834
|
+
})
|
|
835
|
+
.then(data => {
|
|
836
|
+
if (data.error) {
|
|
837
|
+
throw new Error(data.error.message || 'Erreur API YouTube');
|
|
838
|
+
}
|
|
839
|
+
this.generateYouTubeFeed(element, data);
|
|
840
|
+
})
|
|
841
|
+
.catch(error => {
|
|
842
|
+
bbContents.utils.log('Erreur dans le module youtube:', error);
|
|
843
|
+
element.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>`;
|
|
844
|
+
});
|
|
845
|
+
});
|
|
846
|
+
},
|
|
847
|
+
|
|
848
|
+
generateYouTubeFeed: function(container, data) {
|
|
849
|
+
if (!data.items || data.items.length === 0) {
|
|
850
|
+
container.innerHTML = '<div style="padding: 20px; text-align: center; color: #6b7280;">Aucune vidéo trouvée</div>';
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
// Créer la grille de vidéos
|
|
855
|
+
let html = '<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">';
|
|
856
|
+
|
|
857
|
+
data.items.forEach(item => {
|
|
858
|
+
const videoId = item.id.videoId;
|
|
859
|
+
const snippet = item.snippet;
|
|
860
|
+
|
|
861
|
+
html += `
|
|
862
|
+
<div class="bb-youtube-video" style="border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
|
|
863
|
+
<div class="bb-youtube-thumbnail" style="position: relative;">
|
|
864
|
+
<img src="${snippet.thumbnails.medium.url}" alt="${snippet.title}" style="width: 100%; height: auto; display: block;">
|
|
865
|
+
<div class="bb-youtube-duration" style="position: absolute; bottom: 8px; right: 8px; background: rgba(0,0,0,0.8); color: white; padding: 2px 6px; border-radius: 4px; font-size: 12px;">YouTube</div>
|
|
866
|
+
</div>
|
|
867
|
+
<div class="bb-youtube-content" style="padding: 16px;">
|
|
868
|
+
<div class="bb-youtube-title" style="font-weight: 600; margin-bottom: 8px; line-height: 1.4;">${snippet.title}</div>
|
|
869
|
+
<div class="bb-youtube-channel" style="color: #6b7280; font-size: 14px; margin-bottom: 8px;">${snippet.channelTitle}</div>
|
|
870
|
+
<div class="bb-youtube-date" style="color: #9ca3af; font-size: 12px;">${this.formatDate(snippet.publishedAt)}</div>
|
|
871
|
+
</div>
|
|
872
|
+
</div>
|
|
873
|
+
`;
|
|
874
|
+
});
|
|
875
|
+
|
|
876
|
+
html += '</div>';
|
|
877
|
+
container.innerHTML = html;
|
|
878
|
+
|
|
879
|
+
// Traiter les éléments avec des attributes spécifiques
|
|
880
|
+
this.processYouTubeElements(container, data);
|
|
881
|
+
},
|
|
882
|
+
|
|
883
|
+
processYouTubeElements: function(container, data) {
|
|
884
|
+
// Traiter bb-youtube-show-title
|
|
885
|
+
container.querySelectorAll('[bb-youtube-show-title]').forEach((element, index) => {
|
|
886
|
+
if (data.items[index]) {
|
|
887
|
+
element.textContent = data.items[index].snippet.title;
|
|
888
|
+
}
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
// Traiter bb-youtube-show-description
|
|
892
|
+
container.querySelectorAll('[bb-youtube-show-description]').forEach((element, index) => {
|
|
893
|
+
if (data.items[index]) {
|
|
894
|
+
element.textContent = data.items[index].snippet.description;
|
|
895
|
+
}
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
// Traiter bb-youtube-show-views (nécessite une requête supplémentaire)
|
|
899
|
+
container.querySelectorAll('[bb-youtube-show-views]').forEach((element, index) => {
|
|
900
|
+
if (data.items[index]) {
|
|
901
|
+
element.textContent = 'Vues non disponibles';
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
// Traiter bb-youtube-show-date
|
|
906
|
+
container.querySelectorAll('[bb-youtube-show-date]').forEach((element, index) => {
|
|
907
|
+
if (data.items[index]) {
|
|
908
|
+
element.textContent = this.formatDate(data.items[index].snippet.publishedAt);
|
|
909
|
+
}
|
|
910
|
+
});
|
|
911
|
+
},
|
|
912
|
+
|
|
913
|
+
formatDate: function(dateString) {
|
|
914
|
+
const date = new Date(dateString);
|
|
915
|
+
const now = new Date();
|
|
916
|
+
const diffTime = Math.abs(now - date);
|
|
917
|
+
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
|
918
|
+
|
|
919
|
+
if (diffDays === 1) return 'Il y a 1 jour';
|
|
920
|
+
if (diffDays < 7) return `Il y a ${diffDays} jours`;
|
|
921
|
+
if (diffDays < 30) return `Il y a ${Math.floor(diffDays / 7)} semaines`;
|
|
922
|
+
if (diffDays < 365) return `Il y a ${Math.floor(diffDays / 30)} mois`;
|
|
923
|
+
return `Il y a ${Math.floor(diffDays / 365)} ans`;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
};
|
|
796
927
|
|
|
797
928
|
|
|
798
929
|
|