Merge branch 'main' of https://gitea.o2o.kr/castad/o2o-castad-frontend into feature-dashboard
commit
ba4d143189
|
|
@ -21,6 +21,7 @@ interface SavedVideoState {
|
|||
songTaskId: string;
|
||||
status: VideoStatus;
|
||||
videoUrl: string | null;
|
||||
videoDbId?: number;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
|
|
@ -45,6 +46,7 @@ const CompletionContent: React.FC<CompletionContentProps> = ({
|
|||
|
||||
// 소셜 미디어 포스팅 모달
|
||||
const [showSocialModal, setShowSocialModal] = useState(false);
|
||||
const [videoDbId, setVideoDbId] = useState<number | null>(null);
|
||||
|
||||
// 저장된 완료 데이터
|
||||
const [songCompletionData, setSongCompletionData] = useState<{
|
||||
|
|
@ -69,12 +71,13 @@ const CompletionContent: React.FC<CompletionContentProps> = ({
|
|||
}
|
||||
}, [renderProgress, onVideoProgressChange]);
|
||||
|
||||
const saveToStorage = (videoTaskId: string, currentSongTaskId: string, status: VideoStatus, url: string | null) => {
|
||||
const saveToStorage = (videoTaskId: string, currentSongTaskId: string, status: VideoStatus, url: string | null, dbId?: number) => {
|
||||
const data: SavedVideoState = {
|
||||
videoTaskId,
|
||||
songTaskId: currentSongTaskId,
|
||||
status,
|
||||
videoUrl: url,
|
||||
videoDbId: dbId,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
localStorage.setItem(VIDEO_STORAGE_KEY, JSON.stringify(data));
|
||||
|
|
@ -83,6 +86,7 @@ const CompletionContent: React.FC<CompletionContentProps> = ({
|
|||
const completeData = {
|
||||
songTaskId: currentSongTaskId,
|
||||
videoUrl: url,
|
||||
videoDbId: dbId,
|
||||
completedAt: Date.now(),
|
||||
};
|
||||
localStorage.setItem(VIDEO_COMPLETE_KEY, JSON.stringify(completeData));
|
||||
|
|
@ -93,7 +97,7 @@ const CompletionContent: React.FC<CompletionContentProps> = ({
|
|||
localStorage.removeItem(VIDEO_STORAGE_KEY);
|
||||
};
|
||||
|
||||
const loadCompleteVideo = (): { songTaskId: string; videoUrl: string } | null => {
|
||||
const loadCompleteVideo = (): { songTaskId: string; videoUrl: string; videoDbId?: number } | null => {
|
||||
try {
|
||||
const saved = localStorage.getItem(VIDEO_COMPLETE_KEY);
|
||||
if (!saved) return null;
|
||||
|
|
@ -202,10 +206,14 @@ const CompletionContent: React.FC<CompletionContentProps> = ({
|
|||
const videoUrlFromResponse = statusResponse.render_data?.url;
|
||||
|
||||
if (videoUrlFromResponse) {
|
||||
const videoId = statusResponse.render_data?.video_id;
|
||||
setVideoUrl(videoUrlFromResponse);
|
||||
if (videoId) {
|
||||
setVideoDbId(videoId);
|
||||
}
|
||||
setVideoStatus('complete');
|
||||
setStatusMessage('');
|
||||
saveToStorage(videoTaskId, currentSongTaskId, 'complete', videoUrlFromResponse);
|
||||
saveToStorage(videoTaskId, currentSongTaskId, 'complete', videoUrlFromResponse, videoId);
|
||||
} else {
|
||||
throw new Error(t('completion.videoUrlMissing'));
|
||||
}
|
||||
|
|
@ -232,6 +240,7 @@ const CompletionContent: React.FC<CompletionContentProps> = ({
|
|||
const completeVideo = loadCompleteVideo();
|
||||
if (completeVideo && completeVideo.songTaskId === songTaskId && completeVideo.videoUrl) {
|
||||
setVideoUrl(completeVideo.videoUrl);
|
||||
if (completeVideo.videoDbId) setVideoDbId(completeVideo.videoDbId);
|
||||
setVideoStatus('complete');
|
||||
hasStartedGeneration.current = true;
|
||||
return;
|
||||
|
|
@ -242,6 +251,7 @@ const CompletionContent: React.FC<CompletionContentProps> = ({
|
|||
if (savedState && savedState.songTaskId === songTaskId) {
|
||||
if (savedState.status === 'complete' && savedState.videoUrl) {
|
||||
setVideoUrl(savedState.videoUrl);
|
||||
if (savedState.videoDbId) setVideoDbId(savedState.videoDbId);
|
||||
setVideoStatus('complete');
|
||||
hasStartedGeneration.current = true;
|
||||
} else if (savedState.status === 'polling') {
|
||||
|
|
@ -501,7 +511,7 @@ const CompletionContent: React.FC<CompletionContentProps> = ({
|
|||
</button>
|
||||
<button
|
||||
onClick={handleOpenSocialConnect}
|
||||
disabled={videoStatus !== 'complete'}
|
||||
disabled={videoStatus !== 'complete' || !videoDbId}
|
||||
className="comp2-btn comp2-btn-primary"
|
||||
>
|
||||
{t('completion.uploadToSocial', { defaultValue: '소셜 채널 업로드' })}
|
||||
|
|
@ -515,8 +525,8 @@ const CompletionContent: React.FC<CompletionContentProps> = ({
|
|||
<SocialPostingModal
|
||||
isOpen={showSocialModal}
|
||||
onClose={handleCloseSocialConnect}
|
||||
video={videoUrl ? {
|
||||
video_id: 0,
|
||||
video={videoUrl && videoDbId ? {
|
||||
video_id: videoDbId,
|
||||
store_name: songCompletionData?.businessName || '',
|
||||
region: '',
|
||||
task_id: songTaskId || '',
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ export interface VideoStatusResponse {
|
|||
status: string;
|
||||
url: string | null;
|
||||
snapshot_url: string | null;
|
||||
video_id?: number;
|
||||
} | null;
|
||||
raw_response?: Record<string, unknown>;
|
||||
error_message: string | null;
|
||||
|
|
|
|||
|
|
@ -301,6 +301,17 @@ export async function getVideosList(page: number = 1, pageSize: number = 10): Pr
|
|||
return response.json();
|
||||
}
|
||||
|
||||
// task_id로 video_id 조회 (소셜 업로드용)
|
||||
export async function getVideoIdByTaskId(taskId: string): Promise<number | null> {
|
||||
try {
|
||||
const response = await getVideosList(1, 50);
|
||||
const found = response.items.find(v => v.task_id === taskId);
|
||||
return found?.video_id ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 비디오 삭제 API (개별 비디오 삭제)
|
||||
export async function deleteVideo(videoId: number): Promise<void> {
|
||||
const response = await authenticatedFetch(`${API_URL}/archive/videos/${videoId}`, {
|
||||
|
|
|
|||
Loading…
Reference in New Issue