mirror of
https://github.com/R0m1k3/Socialflow.git
synced 2026-10-18 20:56:54 +02:00
Reels : option « Publier aussi en story » sur Facebook
Une case sur les écrans de création (bureau, mobile) et de programmation d'un Reel double la publication d'une story vidéo sur les pages Facebook sélectionnées. TikTok n'ayant pas de stories, l'option ne le concerne pas. - Publication immédiate : la story part juste après le Reel, à partir de la vidéo rendue envoyée en binaire (nouvelle publishVideoStoryFromBuffer). Un échec de la story est noté dans l'historique sans faire échouer le Reel. - Publication programmée : une entrée « story » est planifiée à côté du Reel ; le planificateur la publie comme les autres stories. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPMYHUDaZyrG3xRCM5iGVr
This commit is contained in:
10 files changed
+172
-5
No files matched your search
@@ -0,0 +1,29 @@
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
|
||||
interface StoryToggleProps {
|
||||
checked: boolean;
|
||||
onCheckedChange: (checked: boolean) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Double le Reel d'une story sur les pages Facebook sélectionnées. TikTok n'a
|
||||
* pas de stories : l'option ne le concerne pas.
|
||||
*/
|
||||
export function StoryToggle({ checked, onCheckedChange }: StoryToggleProps) {
|
||||
return (
|
||||
<div className="flex items-center justify-between gap-4 rounded-lg border border-border/50 p-3">
|
||||
<label htmlFor="reel-also-story" className="space-y-0.5 cursor-pointer">
|
||||
<div className="text-sm font-medium">Publier aussi en story</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
La vidéo est aussi publiée en story sur les pages Facebook sélectionnées (visible 24 h).
|
||||
</div>
|
||||
</label>
|
||||
<Switch
|
||||
id="reel-also-story"
|
||||
checked={checked}
|
||||
onCheckedChange={(value) => onCheckedChange(value === true)}
|
||||
data-testid="switch-reel-also-story"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { StoryToggle } from "@/components/reels/story-toggle";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Slider } from "@/components/ui/slider";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
@@ -83,6 +84,7 @@ export default function MobileNewReel() {
|
||||
const [isPlaying, setIsPlaying] = useState<string | null>(null);
|
||||
// Désactivée par défaut : double le temps de rendu, utile seulement pour une vidéo tremblée
|
||||
const [stabilize, setStabilize] = useState(false);
|
||||
const [alsoStory, setAlsoStory] = useState(false);
|
||||
const [enableEndingEffect, setEnableEndingEffect] = useState(true);
|
||||
const [showLogo, setShowLogo] = useState(true);
|
||||
|
||||
@@ -272,6 +274,7 @@ export default function MobileNewReel() {
|
||||
description: srtFile ? srtText(srtFile.cues) : overlayText,
|
||||
pageIds: selectedPages,
|
||||
scheduledFor: scheduledDate?.toISOString(),
|
||||
alsoStory,
|
||||
musicVolume: musicVolume[0] / 100,
|
||||
stabilize: stabilize,
|
||||
drawText: true,
|
||||
@@ -610,6 +613,7 @@ export default function MobileNewReel() {
|
||||
Pages Facebook
|
||||
</div>
|
||||
{facebookPages.map(renderTargetCheckbox)}
|
||||
<StoryToggle checked={alsoStory} onCheckedChange={setAlsoStory} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { StoryToggle } from "@/components/reels/story-toggle";
|
||||
import { Slider } from "@/components/ui/slider";
|
||||
import {
|
||||
Select,
|
||||
@@ -78,6 +79,7 @@ export default function NewReel() {
|
||||
const [drawText, setDrawText] = useState(true);
|
||||
// Désactivée par défaut : double le temps de rendu, utile seulement pour une vidéo tremblée
|
||||
const [stabilize, setStabilize] = useState(false);
|
||||
const [alsoStory, setAlsoStory] = useState(false);
|
||||
const [enableEndingEffect, setEnableEndingEffect] = useState(true);
|
||||
const [showLogo, setShowLogo] = useState(true);
|
||||
|
||||
@@ -415,6 +417,7 @@ export default function NewReel() {
|
||||
description: srtFile ? srtText(srtFile.cues) : overlayText,
|
||||
pageIds: selectedPages,
|
||||
scheduledFor: scheduledDate?.toISOString(),
|
||||
alsoStory,
|
||||
musicVolume: musicVolume[0] / 100,
|
||||
ttsEnabled,
|
||||
ttsEngine,
|
||||
@@ -938,6 +941,7 @@ export default function NewReel() {
|
||||
Pages Facebook
|
||||
</div>
|
||||
{facebookPages.map(renderTargetCheckbox)}
|
||||
<StoryToggle checked={alsoStory} onCheckedChange={setAlsoStory} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { StoryToggle } from "@/components/reels/story-toggle";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { apiRequest, queryClient, handleUnauthorized, getErrorMessage } from "@/lib/queryClient";
|
||||
import type { SocialPage, Media } from "@shared/schema";
|
||||
@@ -30,6 +31,7 @@ export default function ScheduleReel() {
|
||||
const [description, setDescription] = useState("");
|
||||
const [selectedPages, setSelectedPages] = useState<string[]>([]);
|
||||
const [scheduledDate, setScheduledDate] = useState<Date | undefined>(undefined);
|
||||
const [alsoStory, setAlsoStory] = useState(false);
|
||||
|
||||
const { data: pages = [] } = useQuery<SocialPage[]>({ queryKey: ["/api/pages"] });
|
||||
const { data: allMedia = [] } = useQuery<Media[]>({ queryKey: ["/api/media"] });
|
||||
@@ -83,6 +85,7 @@ export default function ScheduleReel() {
|
||||
mediaIds: [selectedVideo!.id],
|
||||
pageIds: selectedPages,
|
||||
scheduledFor: scheduledDate!.toISOString(),
|
||||
alsoStory,
|
||||
});
|
||||
return response.json();
|
||||
},
|
||||
@@ -250,6 +253,7 @@ export default function ScheduleReel() {
|
||||
<SiFacebook className="w-4 h-4 text-[#1877F2]" /> Pages Facebook
|
||||
</Label>
|
||||
{facebookPages.map(renderTargetCheckbox)}
|
||||
<StoryToggle checked={alsoStory} onCheckedChange={setAlsoStory} />
|
||||
</div>
|
||||
)}
|
||||
{tiktokAccounts.length > 0 && (
|
||||
|
||||
Reference in new issue
Block a user