diff --git a/backend/__pycache__/api_routes.cpython-314.pyc b/backend/__pycache__/api_routes.cpython-314.pyc index 3aa3bae..1ffef2e 100644 Binary files a/backend/__pycache__/api_routes.cpython-314.pyc and b/backend/__pycache__/api_routes.cpython-314.pyc differ diff --git a/backend/api_routes.py b/backend/api_routes.py index bfce130..13cc0e1 100644 --- a/backend/api_routes.py +++ b/backend/api_routes.py @@ -96,6 +96,16 @@ def _build_prompt(transcript_text: str, title: str) -> str: f"{transcript_text}\n\n" "Answer user questions grounded in this transcript." ) +def _add_audio_url(post: Dict[str, Any]) -> Dict[str, Any]: + """Add signed audio URL to post if ready""" + if post.get("status") == "ready": + try: + audio_data = get_original_audio_url(post["post_id"], expires_in=3600) + post["audio_url"] = audio_data["signed_url"] + except: + pass + return post + @api.get("/health") @@ -397,20 +407,32 @@ def api_create_post(): return _error(str(e), 500) + @api.get("/posts") def api_list_posts(): page = request.args.get("page", default=1, type=int) limit = request.args.get("limit", default=20, type=int) visibility = request.args.get("visibility") - user_id = request.args.get("user_id", type=int) - + current_user_id = request.args.get("current_user_id", type=int) # NEW LINE + try: - rows = list_audio_posts(page=page, limit=limit, visibility=visibility, user_id=user_id) + rows = list_audio_posts(page=page, limit=limit, visibility=visibility) + + # NEW: Filter private posts + if current_user_id: + rows = [p for p in rows if p.get('visibility') == 'public' or p.get('user_id') == current_user_id] + else: + rows = [p for p in rows if p.get('visibility') == 'public'] + + # NEW: Add audio URLs - CHANGE THIS LINE ONLY + rows = [_add_audio_url(post) for post in rows] + return jsonify({"posts": rows, "page": page, "limit": min(max(1, limit), 100)}) except Exception as e: return _error(str(e), 500) + @api.get("/posts/") def api_get_post(post_id: int): row = get_audio_post_by_id(post_id) @@ -583,20 +605,3 @@ def api_post_audit(post_id: int): return jsonify({"logs": list_audit_logs(post_id=post_id, page=page, limit=limit)}) except Exception as e: return _error(str(e), 500) - -@api.get("/posts//audio") -def api_get_audio_url(post_id: int): - """ - Get a signed URL for the original audio file. - """ - expires_in = request.args.get("expires_in", default=3600, type=int) - - try: - audio_data = get_original_audio_url(post_id, expires_in=expires_in) - return jsonify(audio_data) - except ValueError as e: - return _error(str(e), 404) - except RuntimeError as e: - return _error(str(e), 500) - except Exception as e: - return _error(f"Failed to get audio URL: {e}", 500) diff --git a/frontend/src/api.js b/frontend/src/api.js index 9e0ef6f..9bcd624 100644 --- a/frontend/src/api.js +++ b/frontend/src/api.js @@ -137,6 +137,10 @@ class ApiClient { return this.request(`/posts/${postId}/metadata`); } + async getAudioUrl(postId, expiresIn = 3600) { + return this.request(`/posts/${postId}/audio?expires_in=${expiresIn}`); + } + // ==================== Post Files ==================== async getPostFiles(postId) { diff --git a/frontend/src/components/AudioPostCard.jsx b/frontend/src/components/AudioPostCard.jsx index 3bba9ab..33bcac0 100644 --- a/frontend/src/components/AudioPostCard.jsx +++ b/frontend/src/components/AudioPostCard.jsx @@ -12,6 +12,13 @@ export default function AudioPostCard({ post }) { const [transcriptExpanded, setTranscriptExpanded] = useState(false) const audioRef = useRef(null) + // DEBUG: Log post data to console + useEffect(() => { + console.log('Post data:', post) + console.log('Audio URL:', post.audio_url) + console.log('Status:', post.status) + }, [post]) + const formatDate = (dateString) => { const date = new Date(dateString) const now = new Date() @@ -35,7 +42,14 @@ export default function AudioPostCard({ post }) { if (post.status === 'ready' && !transcript && !loadingTranscript) { loadTranscript() } - }, [post.post_id, post.status]) + + // Set audio source if available + if (post.audio_url && audioRef.current) { + console.log('Setting audio src to:', post.audio_url) + audioRef.current.src = post.audio_url + audioRef.current.load() // Force reload + } + }, [post.post_id, post.status, post.audio_url]) const loadTranscript = async () => { setLoadingTranscript(true) @@ -78,10 +92,16 @@ export default function AudioPostCard({ post }) { const handleLoadedMetadata = () => { if (audioRef.current) { + console.log('Audio metadata loaded, duration:', audioRef.current.duration) setDuration(audioRef.current.duration) } } + const handleAudioError = (e) => { + console.error('Audio error:', e) + console.error('Audio element error:', audioRef.current?.error) + } + const handleSeek = (e) => { const rect = e.currentTarget.getBoundingClientRect() const x = e.clientX - rect.left @@ -155,11 +175,13 @@ export default function AudioPostCard({ post }) { {/* Hidden audio element */}