diff --git a/backend/__pycache__/api_routes.cpython-314.pyc b/backend/__pycache__/api_routes.cpython-314.pyc index b7cc98c..78e5b27 100644 Binary files a/backend/__pycache__/api_routes.cpython-314.pyc and b/backend/__pycache__/api_routes.cpython-314.pyc differ diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 02a7bcf..f8c261a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,9 +9,11 @@ "version": "0.0.0", "dependencies": { "@tailwindcss/vite": "^4.1.18", + "howler": "^2.2.4", "lucide-react": "^0.564.0", "react": "^19.2.0", "react-dom": "^19.2.0", + "react-howler": "^5.2.0", "tailwindcss": "^4.1.18" }, "devDependencies": { @@ -2369,6 +2371,12 @@ "hermes-estree": "0.25.1" } }, + "node_modules/howler": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/howler/-/howler-2.2.4.tgz", + "integrity": "sha512-iARIBPgcQrwtEr+tALF+rapJ8qSc+Set2GJQl7xT1MQzWaVkFebdJhR3alVlSiUf5U7nAANKuj3aWpwerocD5w==", + "license": "MIT" + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -2449,7 +2457,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, "license": "MIT" }, "node_modules/js-yaml": { @@ -2808,6 +2815,18 @@ "dev": true, "license": "MIT" }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2888,6 +2907,15 @@ "dev": true, "license": "MIT" }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -3027,6 +3055,17 @@ "node": ">= 0.8.0" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3058,6 +3097,22 @@ "react": "^19.2.4" } }, + "node_modules/react-howler": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-howler/-/react-howler-5.2.0.tgz", + "integrity": "sha512-oDK+zML0MHf3nVNM4lMxh+re87NDa7fHowea2WK8197yqnMiZfPVHoMXtfb/PtuoOsWLO06vmEAtovwTRWpTFg==", + "license": "MIT", + "dependencies": { + "howler": "^2.2.0", + "prop-types": "^15.5.6" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/react-refresh": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index a95c3ef..12cfaf6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,9 +11,11 @@ }, "dependencies": { "@tailwindcss/vite": "^4.1.18", + "howler": "^2.2.4", "lucide-react": "^0.564.0", "react": "^19.2.0", "react-dom": "^19.2.0", + "react-howler": "^5.2.0", "tailwindcss": "^4.1.18" }, "devDependencies": { diff --git a/frontend/public/logo-prev.png b/frontend/public/logo-prev.png new file mode 100644 index 0000000..873c286 Binary files /dev/null and b/frontend/public/logo-prev.png differ diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index a875dff..7e420b7 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -209,10 +209,10 @@ export default function App() { // Main App return ( -
+
-
+
diff --git a/frontend/src/components/AudioPostCard.jsx b/frontend/src/components/AudioPostCard.jsx index 5705e4c..7c4a252 100644 --- a/frontend/src/components/AudioPostCard.jsx +++ b/frontend/src/components/AudioPostCard.jsx @@ -21,16 +21,14 @@ export default function AudioPostCard({ post, onViewPost }) { }, [post]) const formatDate = (dateString) => { - const date = new Date(dateString) - const now = new Date() - const diffMs = now - date - const diffMins = Math.floor(diffMs / 60000) - - if (diffMins < 60) return `${diffMins}m ago` - if (diffMins < 1440) return `${Math.floor(diffMins / 60)}h ago` - return `${Math.floor(diffMins / 1440)}d ago` + return new Date(dateString).toLocaleDateString('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + hour: '2-digit', + minute: '2-digit' + }) } - const formatTime = (seconds) => { if (!seconds || isNaN(seconds)) return '0:00' const mins = Math.floor(seconds / 60) @@ -298,41 +296,18 @@ export default function AudioPostCard({ post, onViewPost }) {
{/* Transcript Section - Always shown */} -
- - - {transcript && ( -
-
-

- {transcript} -

-
-
- )} - - {!transcript && !loadingTranscript && ( -
-

No transcript available

-
- )} - - {loadingTranscript && ( -
-

Loading transcript...

-
+
+ {transcript ? ( +

+ {transcript} +

+ ) : ( +

No transcript available

)}
+ + + )} diff --git a/frontend/src/pages/PostDetail.jsx b/frontend/src/pages/PostDetail.jsx index dd575b5..09994b4 100644 --- a/frontend/src/pages/PostDetail.jsx +++ b/frontend/src/pages/PostDetail.jsx @@ -16,7 +16,6 @@ export default function PostDetail({ postId, user, onBack }) { const [volume, setVolume] = useState(1) const [downloading, setDownloading] = useState(false) const audioRef = useRef(null) - const [audioSrc, setAudioSrc] = useState(null) useEffect(() => { if (postId) { @@ -24,6 +23,16 @@ export default function PostDetail({ postId, user, onBack }) { } }, [postId]) + // Add this useEffect in PostDetail +useEffect(() => { + if (audioRef.current && post?.audio_url) { + console.log('Setting audio src:', post.audio_url) + audioRef.current.src = post.audio_url + audioRef.current.load() // Force reload + } +}, [post?.audio_url]) + + const loadPostData = async () => { setLoading(true) setError(null) @@ -35,8 +44,6 @@ export default function PostDetail({ postId, user, onBack }) { // Load audio URL if available if (postData.audio_url && audioRef.current) { - setPost(postData) - setAudioSrc(postData.audio_url) audioRef.current.src = postData.audio_url audioRef.current.load() } @@ -293,14 +300,12 @@ export default function PostDetail({ postId, user, onBack }) {