Skip to content

Commit 9306da4

Browse files
committed
don't close camera during countdown
1 parent b402cee commit 9306da4

File tree

3 files changed

+57
-16
lines changed

3 files changed

+57
-16
lines changed

apps/desktop/src-tauri/src/lib.rs

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use general_settings::GeneralSettingsStore;
4242
use mp4::Mp4Reader;
4343
use notifications::NotificationType;
4444
use png::{ColorType, Encoder};
45-
use recording::InProgressRecording;
45+
use recording::{InProgressRecording, StartRecordingInputs};
4646
use relative_path::RelativePathBuf;
4747

4848
use scap::capturer::Capturer;
@@ -85,6 +85,12 @@ use windows::EditorWindowIds;
8585
use windows::set_window_transparent;
8686
use windows::{CapWindowId, ShowCapWindow};
8787

88+
pub enum RecordingState {
89+
None,
90+
Pending,
91+
Active(InProgressRecording),
92+
}
93+
8894
#[derive(specta::Type, Serialize)]
8995
#[serde(rename_all = "camelCase")]
9096
pub struct App {
@@ -104,7 +110,7 @@ pub struct App {
104110
#[serde(skip)]
105111
handle: AppHandle,
106112
#[serde(skip)]
107-
current_recording: Option<InProgressRecording>,
113+
recording_state: RecordingState,
108114
#[serde(skip)]
109115
recording_logging_handle: LoggingHandle,
110116
server_url: String,
@@ -140,16 +146,27 @@ pub struct VideoUploadInfo {
140146
}
141147

142148
impl App {
143-
pub fn set_current_recording(&mut self, actor: InProgressRecording) {
144-
self.current_recording = Some(actor);
149+
pub fn set_pending_recording(&mut self) {
150+
self.recording_state = RecordingState::Pending;
151+
CurrentRecordingChanged.emit(&self.handle).ok();
152+
}
145153

154+
pub fn set_current_recording(&mut self, actor: InProgressRecording) {
155+
self.recording_state = RecordingState::Active(actor);
146156
CurrentRecordingChanged.emit(&self.handle).ok();
147157
}
148158

149159
pub fn clear_current_recording(&mut self) -> Option<InProgressRecording> {
150-
self.close_occluder_windows();
151-
152-
self.current_recording.take()
160+
match std::mem::replace(&mut self.recording_state, RecordingState::None) {
161+
RecordingState::Active(recording) => {
162+
self.close_occluder_windows();
163+
Some(recording)
164+
}
165+
_ => {
166+
self.close_occluder_windows();
167+
None
168+
}
169+
}
153170
}
154171

155172
fn close_occluder_windows(&self) {
@@ -175,6 +192,24 @@ impl App {
175192

176193
Ok(())
177194
}
195+
196+
pub fn current_recording(&self) -> Option<&InProgressRecording> {
197+
match &self.recording_state {
198+
RecordingState::Active(recording) => Some(recording),
199+
_ => None,
200+
}
201+
}
202+
203+
pub fn current_recording_mut(&mut self) -> Option<&mut InProgressRecording> {
204+
match &mut self.recording_state {
205+
RecordingState::Active(recording) => Some(recording),
206+
_ => None,
207+
}
208+
}
209+
210+
pub fn is_recording_active_or_pending(&self) -> bool {
211+
!matches!(self.recording_state, RecordingState::None)
212+
}
178213
}
179214

180215
#[tauri::command]
@@ -389,7 +424,7 @@ async fn get_current_recording(
389424
state: MutableState<'_, App>,
390425
) -> Result<JsonValue<Option<CurrentRecording>>, ()> {
391426
let state = state.read().await;
392-
Ok(JsonValue::new(&state.current_recording.as_ref().map(|r| {
427+
Ok(JsonValue::new(&state.current_recording().map(|r| {
393428
let bounds = r.bounds();
394429

395430
let target = match r.capture_target() {
@@ -2041,7 +2076,7 @@ pub async fn run(recording_logging_handle: LoggingHandle) {
20412076
camera_feed_initialization: None,
20422077
mic_samples_tx: audio_input_tx,
20432078
mic_feed: None,
2044-
current_recording: None,
2079+
recording_state: RecordingState::None,
20452080
recording_logging_handle,
20462081
server_url: GeneralSettingsStore::get(&app)
20472082
.ok()
@@ -2130,7 +2165,7 @@ pub async fn run(recording_logging_handle: LoggingHandle) {
21302165
let state = app.state::<Arc<RwLock<App>>>();
21312166
let app_state = &mut *state.write().await;
21322167

2133-
if app_state.current_recording.is_none() {
2168+
if !app_state.is_recording_active_or_pending() {
21342169
app_state.mic_feed.take();
21352170
app_state.camera_feed.take();
21362171

apps/desktop/src-tauri/src/recording.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ pub fn list_cameras() -> Vec<cap_camera::CameraInfo> {
192192
CameraFeed::list_cameras()
193193
}
194194

195-
#[derive(Deserialize, Type, Clone)]
195+
#[derive(Deserialize, Type, Clone, Debug)]
196196
pub struct StartRecordingInputs {
197197
pub capture_target: ScreenCaptureTarget,
198198
#[serde(default)]
@@ -327,6 +327,12 @@ pub async fn start_recording(
327327
_ => {}
328328
}
329329

330+
// Set pending state BEFORE closing main window and starting countdown
331+
{
332+
let mut state = state_mtx.write().await;
333+
state.set_pending_recording();
334+
}
335+
330336
if let Some(window) = CapWindowId::Main.get(&app) {
331337
let _ = general_settings
332338
.map(|v| v.main_window_recording_start_behaviour)
@@ -496,7 +502,7 @@ pub async fn start_recording(
496502
pub async fn pause_recording(state: MutableState<'_, App>) -> Result<(), String> {
497503
let mut state = state.write().await;
498504

499-
if let Some(recording) = state.current_recording.as_mut() {
505+
if let Some(recording) = state.current_recording_mut() {
500506
recording.pause().await.map_err(|e| e.to_string())?;
501507
}
502508

@@ -508,7 +514,7 @@ pub async fn pause_recording(state: MutableState<'_, App>) -> Result<(), String>
508514
pub async fn resume_recording(state: MutableState<'_, App>) -> Result<(), String> {
509515
let mut state = state.write().await;
510516

511-
if let Some(recording) = state.current_recording.as_mut() {
517+
if let Some(recording) = state.current_recording_mut() {
512518
recording.resume().await.map_err(|e| e.to_string())?;
513519
}
514520

@@ -595,7 +601,7 @@ async fn handle_recording_end(
595601
app: &mut App,
596602
) -> Result<(), String> {
597603
// Clear current recording, just in case :)
598-
app.current_recording.take();
604+
app.clear_current_recording();
599605

600606
let res = if let Some(recording) = recording {
601607
// we delay reporting errors here so that everything else happens first

apps/desktop/src/utils/tauri.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,8 +383,8 @@ export type PresetsStore = { presets: Preset[]; default: number | null }
383383
export type ProjectConfiguration = { aspectRatio: AspectRatio | null; background: BackgroundConfiguration; camera: Camera; audio: AudioConfiguration; cursor: CursorConfiguration; hotkeys: HotkeysConfiguration; timeline?: TimelineConfiguration | null; captions?: CaptionsData | null }
384384
export type ProjectRecordingsMeta = { segments: SegmentRecordings[] }
385385
export type RecordingEvent = { variant: "Countdown"; value: number } | { variant: "Started" } | { variant: "Stopped" } | { variant: "Failed"; error: string }
386-
export type RecordingMeta = (StudioRecordingMeta | InstantRecordingMeta) & { platform: Platform | null; pretty_name: string; sharing?: SharingMeta | null }
387-
export type RecordingMetaWithType = ((StudioRecordingMeta | InstantRecordingMeta) & { platform: Platform | null; pretty_name: string; sharing?: SharingMeta | null }) & { type: RecordingType }
386+
export type RecordingMeta = (StudioRecordingMeta | InstantRecordingMeta) & { platform?: Platform | null; pretty_name: string; sharing?: SharingMeta | null }
387+
export type RecordingMetaWithType = ((StudioRecordingMeta | InstantRecordingMeta) & { platform?: Platform | null; pretty_name: string; sharing?: SharingMeta | null }) & { type: RecordingType }
388388
export type RecordingMode = "studio" | "instant"
389389
export type RecordingOptionsChanged = null
390390
export type RecordingStarted = null

0 commit comments

Comments
 (0)