1use edit::EditProject;
12use leptos::prelude::*;
13
14use crate::editor_ipc::{self, ExportUiState, export_percent};
15
16type ProjectSignal = Option<RwSignal<Option<EditProject>>>;
17
18fn idle_view(
21 project: ProjectSignal,
22 state: RwSignal<ExportUiState>,
23 status: Option<String>,
24 saved: Option<String>,
25) -> AnyView {
26 view! {
27 <div class="export-bar-row">
28 <button
29 class="export-btn"
30 on:click=move |_| {
31 if let Some(p) = project
32 && let Some(proj) = p.get_untracked()
33 {
34 state.set(ExportUiState::Running {
35 done: 0,
36 total: proj.project_duration(),
37 });
38 editor_ipc::editor_export(&proj, "mp4");
39 }
40 }
41 >
42 "Export mp4"
43 </button>
44 <button
45 class="export-save"
46 on:click=move |_| {
47 if let Some(p) = project
48 && let Some(proj) = p.get_untracked()
49 {
50 editor_ipc::editor_save_project(&proj);
51 }
52 }
53 >
54 "Save"
55 </button>
56 {status.map(|msg| view! { <span class="export-status">{msg}</span> })}
57 {saved.map(|path| view! { <span class="export-status">{format!("Saved: {path}")}</span> })}
58 </div>
59 }
60 .into_any()
61}
62
63fn running_view(done: u64, total: u64) -> AnyView {
65 let pct = export_percent(done, total);
66 view! {
67 <div class="export-bar-row">
68 <div class="export-progress">
69 <div class="export-progress-fill" style=format!("width:{pct}%")></div>
70 </div>
71 <span class="export-pct">{format!("{pct}%")}</span>
72 <button class="export-cancel" on:click=move |_| editor_ipc::editor_export_cancel()>
73 "Cancel"
74 </button>
75 </div>
76 }
77 .into_any()
78}
79
80#[component]
82pub fn ExportBar() -> impl IntoView {
83 let project = use_context::<RwSignal<Option<EditProject>>>();
84 let state = use_context::<RwSignal<ExportUiState>>()
85 .unwrap_or_else(|| RwSignal::new(ExportUiState::Idle));
86 let saved = use_context::<RwSignal<Option<String>>>();
87 view! {
88 <div class="export-bar">
89 <h3 class="clip-inspector-title">"Export"</h3>
90 {move || {
91 let saved_now = saved.and_then(|s| s.get());
92 match state.get() {
93 ExportUiState::Idle => idle_view(project, state, None, saved_now),
94 ExportUiState::Running { done, total } => running_view(done, total),
95 ExportUiState::Done { path } => {
96 idle_view(project, state, Some(format!("✓ Exported: {path}")), saved_now)
97 }
98 ExportUiState::Error { message } => {
99 idle_view(project, state, Some(format!("✗ {message}")), saved_now)
100 }
101 }
102 }}
103 </div>
104 }
105}