Переглянути джерело

Fix: Improve YouTube URL handling

Improve YouTube URL handling and add more explicit instructions.
gpt-engineer-app[bot] 5 місяців тому
батько
коміт
b3a212d850
2 змінених файлів з 56 додано та 14 видалено
  1. 34 9
      src/components/FeedForm.tsx
  2. 22 5
      src/utils/youtube.ts

+ 34 - 9
src/components/FeedForm.tsx

@@ -1,4 +1,3 @@
-
 import { useState } from 'react';
 import { useForm } from 'react-hook-form';
 import { Button } from '@/components/ui/button';
@@ -13,9 +12,17 @@ import {
   FormMessage,
 } from '@/components/ui/form';
 import { DialogFooter } from '@/components/ui/dialog';
-import { convertYouTubeToRSS, fetchYouTubeChannelName } from '@/utils/youtube';
+import { Alert, AlertDescription } from '@/components/ui/alert';
+import { 
+  convertYouTubeToRSS, 
+  fetchYouTubeChannelName, 
+  needsChannelIdLookup, 
+  getChannelIdInstructions,
+  isDirectRSSFeed
+} from '@/utils/youtube';
 import { feedTypeOptions } from './FeedTypeOptions';
 import { NewsCategory } from '@/types/news';
+import { AlertTriangle, Info } from 'lucide-react';
 
 interface FeedFormData {
   name: string;
@@ -34,6 +41,7 @@ interface FeedFormProps {
 const FeedForm = ({ selectedType, onSubmit, onCancel, categories }: FeedFormProps) => {
   const [isLoadingChannelName, setIsLoadingChannelName] = useState(false);
   const [urlWarning, setUrlWarning] = useState<string | null>(null);
+  const [showInstructions, setShowInstructions] = useState(false);
   
   const form = useForm<FeedFormData>({
     defaultValues: {
@@ -66,6 +74,7 @@ const FeedForm = ({ selectedType, onSubmit, onCancel, categories }: FeedFormProp
   const handleUrlChange = async (url: string) => {
     form.setValue('url', url);
     setUrlWarning(null);
+    setShowInstructions(false);
     
     // If it's a YouTube URL and we don't have a name yet, try to fetch it
     if (selectedType === 'youtube' && url && !form.getValues('name')) {
@@ -73,9 +82,14 @@ const FeedForm = ({ selectedType, onSubmit, onCancel, categories }: FeedFormProp
       if (isYouTubeUrl) {
         setIsLoadingChannelName(true);
         
+        // Check if it's a direct RSS feed
+        if (isDirectRSSFeed(url)) {
+          setUrlWarning(null);
+        }
         // Check if it's a custom username that might not work directly
-        if (url.includes('/@') && !url.includes('/channel/')) {
-          setUrlWarning('Note: Les URL avec @username peuvent nécessiter l\'ID de chaîne réel (UC...) pour fonctionner. Si le flux ne fonctionne pas, trouvez l\'ID de chaîne sur YouTube.');
+        else if (needsChannelIdLookup(url)) {
+          setUrlWarning('Cette URL pourrait ne pas fonctionner. Pour de meilleurs résultats, utilisez l\'ID de chaîne (UC...).');
+          setShowInstructions(true);
         }
         
         const channelName = await fetchYouTubeChannelName(url);
@@ -92,7 +106,7 @@ const FeedForm = ({ selectedType, onSubmit, onCancel, categories }: FeedFormProp
   const getUrlPlaceholder = () => {
     switch (selectedType) {
       case 'youtube':
-        return 'https://www.youtube.com/@channelname ou https://www.youtube.com/channel/UCxxxxx';
+        return 'https://www.youtube.com/channel/UCxxxxx ou https://www.youtube.com/feeds/videos.xml?channel_id=UCxxxxx';
       case 'rss-auto':
       case 'rss-manual':
         return 'https://example.com/feed.xml';
@@ -103,7 +117,7 @@ const FeedForm = ({ selectedType, onSubmit, onCancel, categories }: FeedFormProp
 
   const getUrlHelperText = () => {
     if (selectedType === 'youtube') {
-      return 'Pour de meilleurs résultats, utilisez l\'URL avec l\'ID de chaîne (commençant par UC...) si possible';
+      return 'Utilisez de préférence l\'URL avec l\'ID de chaîne (UC...) ou l\'URL RSS directe pour éviter les erreurs';
     }
     return null;
   };
@@ -169,9 +183,20 @@ const FeedForm = ({ selectedType, onSubmit, onCancel, categories }: FeedFormProp
                 </p>
               )}
               {urlWarning && (
-                <p className="text-xs text-yellow-600 mt-1">
-                  ⚠️ {urlWarning}
-                </p>
+                <Alert className="mt-2">
+                  <AlertTriangle className="h-4 w-4" />
+                  <AlertDescription className="text-sm">
+                    {urlWarning}
+                  </AlertDescription>
+                </Alert>
+              )}
+              {showInstructions && selectedType === 'youtube' && (
+                <Alert className="mt-2">
+                  <Info className="h-4 w-4" />
+                  <AlertDescription className="text-sm whitespace-pre-line">
+                    {getChannelIdInstructions()}
+                  </AlertDescription>
+                </Alert>
               )}
               <FormMessage />
             </FormItem>

+ 22 - 5
src/utils/youtube.ts

@@ -21,10 +21,15 @@ export const extractYouTubeChannelId = (url: string): string | null => {
   return null;
 };
 
+// Function to detect if a URL is a direct RSS feed
+export const isDirectRSSFeed = (url: string): boolean => {
+  return url.includes('feeds/videos.xml?channel_id=');
+};
+
 // Function to convert YouTube channel URL to RSS feed URL
 export const convertYouTubeToRSS = (url: string): string => {
   // If it's already an RSS feed URL, return as is
-  if (url.includes('feeds/videos.xml')) {
+  if (isDirectRSSFeed(url)) {
     return url;
   }
 
@@ -32,13 +37,11 @@ export const convertYouTubeToRSS = (url: string): string => {
   
   if (channelId) {
     // For channel ID format (starts with UC), we can directly create the RSS URL
-    if (url.includes('/channel/') || channelId.startsWith('UC')) {
+    if (url.includes('/channel/') && channelId.startsWith('UC')) {
       return `https://www.youtube.com/feeds/videos.xml?channel_id=${channelId}`;
     }
     
-    // For other formats (@username, /c/, /user/), we need to note that
-    // these might not work directly and may need manual channel ID lookup
-    // For now, we'll try with the extracted identifier but add a warning
+    // For other formats, warn that it might not work
     console.warn(`YouTube RSS URL might not work for custom username: ${channelId}. You may need to find the actual channel ID starting with 'UC'`);
     return `https://www.youtube.com/feeds/videos.xml?channel_id=${channelId}`;
   }
@@ -70,6 +73,20 @@ export const extractChannelNameFromUrl = (url: string): string | null => {
   return null;
 };
 
+// Function to check if URL needs channel ID lookup
+export const needsChannelIdLookup = (url: string): boolean => {
+  return url.includes('/@') || url.includes('/c/') || url.includes('/user/');
+};
+
+// Function to get instructions for finding channel ID
+export const getChannelIdInstructions = (): string => {
+  return `Pour trouver l'ID de chaîne YouTube :
+1. Allez sur la page de la chaîne
+2. Clic droit → "Afficher le code source"
+3. Cherchez "channelId":"UC..." ou regardez les liens RSS
+4. Utilisez l'URL complète : https://www.youtube.com/channel/UCxxxxx`;
+};
+
 // Function to fetch YouTube channel name from page metadata with fallback
 export const fetchYouTubeChannelName = async (url: string): Promise<string | null> => {
   // First, try to extract name from URL if it's an @username format