@@ -4,6 +4,7 @@ use crate::web_api::ManagerExt;
4
4
use crate :: { UploadProgress , VideoUploadInfo } ;
5
5
use axum:: body:: Body ;
6
6
use bytes:: Bytes ;
7
+ use cap_project:: { RecordingMeta , RecordingMetaInner , UploadState } ;
7
8
use cap_utils:: spawn_actor;
8
9
use ffmpeg:: ffi:: AV_TIME_BASE ;
9
10
use flume:: Receiver ;
@@ -24,6 +25,7 @@ use std::{
24
25
} ;
25
26
use tauri:: { AppHandle , ipc:: Channel } ;
26
27
use tauri_plugin_clipboard_manager:: ClipboardExt ;
28
+ use tauri_specta:: Event ;
27
29
use tokio:: fs:: File ;
28
30
use tokio:: io:: { AsyncReadExt , AsyncSeekExt } ;
29
31
use tokio:: sync:: watch;
@@ -531,9 +533,16 @@ pub fn bytes_into_stream(
531
533
( stream, total_size as u64 )
532
534
}
533
535
536
+ #[ derive( Clone , Serialize , Type , tauri_specta:: Event ) ]
537
+ pub struct UploadProgressEvent {
538
+ video_id : String ,
539
+ // TODO: Account for different states -> Eg. uploading video vs thumbnail
540
+ uploaded : String ,
541
+ total : String ,
542
+ }
543
+
534
544
// a typical recommended chunk size is 5MB (AWS min part size).
535
545
const CHUNK_SIZE : u64 = 5 * 1024 * 1024 ; // 5MB
536
- // const MIN_PART_SIZE: u64 = 5 * 1024 * 1024; // For non-final parts
537
546
538
547
#[ derive( Serialize ) ]
539
548
#[ serde( rename_all = "camelCase" ) ]
@@ -558,6 +567,7 @@ impl InstantMultipartUpload {
558
567
file_path : PathBuf ,
559
568
pre_created_video : VideoUploadInfo ,
560
569
realtime_upload_done : Option < Receiver < ( ) > > ,
570
+ recording_dir : PathBuf ,
561
571
) -> Self {
562
572
Self {
563
573
handle : spawn_actor ( Self :: run (
@@ -566,6 +576,7 @@ impl InstantMultipartUpload {
566
576
file_path,
567
577
pre_created_video,
568
578
realtime_upload_done,
579
+ recording_dir,
569
580
) ) ,
570
581
}
571
582
}
@@ -576,7 +587,13 @@ impl InstantMultipartUpload {
576
587
file_path : PathBuf ,
577
588
pre_created_video : VideoUploadInfo ,
578
589
realtime_video_done : Option < Receiver < ( ) > > ,
590
+ recording_dir : PathBuf ,
579
591
) -> Result < ( ) , String > {
592
+ // TODO: Reuse this + error handling
593
+ let mut project_meta = RecordingMeta :: load_for_project ( & recording_dir) . unwrap ( ) ;
594
+ project_meta. upload = Some ( UploadState :: MultipartUpload ) ;
595
+ project_meta. save_for_project ( ) . unwrap ( ) ;
596
+
580
597
// --------------------------------------------
581
598
// basic constants and info for chunk approach
582
599
// --------------------------------------------
@@ -751,6 +768,11 @@ impl InstantMultipartUpload {
751
768
}
752
769
}
753
770
771
+ // TODO: Reuse this + error handling
772
+ let mut project_meta = RecordingMeta :: load_for_project ( & recording_dir) . unwrap ( ) ;
773
+ project_meta. upload = Some ( UploadState :: Complete ) ;
774
+ project_meta. save_for_project ( ) . unwrap ( ) ;
775
+
754
776
// Copy link to clipboard early
755
777
let _ = app. clipboard ( ) . write_text ( pre_created_video. link . clone ( ) ) ;
756
778
@@ -882,8 +904,6 @@ impl InstantMultipartUpload {
882
904
}
883
905
} ;
884
906
885
- progress. update ( expected_pos, file_size) ;
886
-
887
907
if !presign_response. status ( ) . is_success ( ) {
888
908
let status = presign_response. status ( ) ;
889
909
let error_body = presign_response
@@ -993,6 +1013,15 @@ impl InstantMultipartUpload {
993
1013
( * last_uploaded_position as f64 / file_size as f64 * 100.0 ) as u32
994
1014
) ;
995
1015
1016
+ progress. update ( expected_pos, file_size) ;
1017
+ UploadProgressEvent {
1018
+ video_id : video_id. to_string ( ) ,
1019
+ uploaded : last_uploaded_position. to_string ( ) ,
1020
+ total : file_size. to_string ( ) ,
1021
+ }
1022
+ . emit ( app)
1023
+ . ok ( ) ;
1024
+
996
1025
let part = UploadedPart {
997
1026
part_number : * part_number,
998
1027
etag,
0 commit comments