feat: not working download zip file
This commit is contained in:
@@ -41,7 +41,7 @@ class ApiClient {
|
||||
}
|
||||
|
||||
// ==================== Auth ====================
|
||||
|
||||
|
||||
async register(email, password, displayName = null) {
|
||||
return this.request('/auth/register', {
|
||||
method: 'POST',
|
||||
@@ -58,12 +58,12 @@ class ApiClient {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
|
||||
|
||||
// Store user ID for subsequent requests
|
||||
if (response.user?.user_id) {
|
||||
this.setUserId(response.user.user_id);
|
||||
}
|
||||
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ class ApiClient {
|
||||
|
||||
async uploadPost(formData) {
|
||||
const url = `${this.baseUrl}/posts/upload`;
|
||||
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
@@ -103,7 +103,7 @@ class ApiClient {
|
||||
|
||||
async getPosts(params = {}) {
|
||||
const queryParams = new URLSearchParams();
|
||||
|
||||
|
||||
if (params.page) queryParams.append('page', params.page);
|
||||
if (params.limit) queryParams.append('limit', params.limit);
|
||||
if (params.visibility) queryParams.append('visibility', params.visibility);
|
||||
@@ -153,6 +153,12 @@ class ApiClient {
|
||||
return this.request(`/posts/${postId}/metadata`);
|
||||
}
|
||||
|
||||
async exportPost(postId) {
|
||||
const response = await fetch(`/api/posts/${postId}/download`, { method: "GET" });
|
||||
if (!response.ok) throw new Error(`Failed to download post: ${response.statusText}`);
|
||||
return await response.blob(); // returns proper Blob ready for download
|
||||
}
|
||||
|
||||
// ==================== RAG Search ====================
|
||||
|
||||
async searchRAG(query, userId, page = 1, limit = 30) {
|
||||
@@ -174,7 +180,7 @@ class ApiClient {
|
||||
|
||||
async getAuditLogs(params = {}) {
|
||||
const queryParams = new URLSearchParams();
|
||||
|
||||
|
||||
if (params.post_id) queryParams.append('post_id', params.post_id);
|
||||
if (params.user_id) queryParams.append('user_id', params.user_id);
|
||||
if (params.page) queryParams.append('page', params.page);
|
||||
|
||||
@@ -24,7 +24,7 @@ export default function AudioPostCard({ post }) {
|
||||
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`
|
||||
@@ -42,7 +42,7 @@ export default function AudioPostCard({ post }) {
|
||||
if (post.status === 'ready' && !transcript && !loadingTranscript) {
|
||||
loadTranscript()
|
||||
}
|
||||
|
||||
|
||||
// Set audio source if available
|
||||
if (post.audio_url && audioRef.current) {
|
||||
console.log('Setting audio src to:', post.audio_url)
|
||||
@@ -75,7 +75,7 @@ export default function AudioPostCard({ post }) {
|
||||
|
||||
const togglePlay = () => {
|
||||
if (!audioRef.current) return
|
||||
|
||||
|
||||
if (isPlaying) {
|
||||
audioRef.current.pause()
|
||||
} else {
|
||||
@@ -107,7 +107,7 @@ export default function AudioPostCard({ post }) {
|
||||
const x = e.clientX - rect.left
|
||||
const percentage = x / rect.width
|
||||
const newTime = percentage * duration
|
||||
|
||||
|
||||
if (audioRef.current) {
|
||||
audioRef.current.currentTime = newTime
|
||||
setCurrentTime(newTime)
|
||||
@@ -122,6 +122,24 @@ export default function AudioPostCard({ post }) {
|
||||
}
|
||||
}
|
||||
|
||||
const handleDownload = async () => {
|
||||
try {
|
||||
const zipBlob = await api.exportPost(post.post_id);
|
||||
|
||||
const url = window.URL.createObjectURL(zipBlob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = `${post.title.replace(/\s+/g, "_")}.zip`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
window.URL.revokeObjectURL(url);
|
||||
} catch (err) {
|
||||
console.error("Failed to download post:", err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const handleEnded = () => {
|
||||
setIsPlaying(false)
|
||||
setCurrentTime(0)
|
||||
@@ -156,6 +174,15 @@ export default function AudioPostCard({ post }) {
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{post.status === "ready" && (
|
||||
<button
|
||||
onClick={handleDownload}
|
||||
className="mt-2 px-3 py-1 bg-[#f4b840] text-black rounded hover:bg-[#e5a930] transition-colors"
|
||||
>
|
||||
Download Post
|
||||
</button>
|
||||
)}
|
||||
|
||||
<button className="text-gray-500 hover:text-gray-700">
|
||||
<MoreVertical size={18} />
|
||||
</button>
|
||||
@@ -185,7 +212,7 @@ export default function AudioPostCard({ post }) {
|
||||
/>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<button
|
||||
<button
|
||||
onClick={togglePlay}
|
||||
className="w-10 h-10 bg-[#f4b840] hover:bg-[#e5a930] rounded-full flex items-center justify-center text-[#1a1a1a] transition-colors"
|
||||
>
|
||||
@@ -196,11 +223,11 @@ export default function AudioPostCard({ post }) {
|
||||
)}
|
||||
</button>
|
||||
<div className="flex-1">
|
||||
<div
|
||||
<div
|
||||
className="h-1.5 bg-gray-300 rounded-full overflow-hidden mb-2 cursor-pointer"
|
||||
onClick={handleSeek}
|
||||
>
|
||||
<div
|
||||
<div
|
||||
className="h-full bg-[#f4b840] rounded-full transition-all"
|
||||
style={{ width: `${progress}%` }}
|
||||
></div>
|
||||
@@ -241,7 +268,7 @@ export default function AudioPostCard({ post }) {
|
||||
transcriptExpanded ? <ChevronUp size={18} /> : <ChevronDown size={18} />
|
||||
)}
|
||||
</button>
|
||||
|
||||
|
||||
{transcript && (
|
||||
<div className={`bg-white transition-all ${transcriptExpanded ? 'max-h-96' : 'max-h-24'} overflow-y-auto`}>
|
||||
<div className="p-4">
|
||||
|
||||
Reference in New Issue
Block a user