diff --git a/src/components/ai-edition/v4/V4Timeline.geometry.test.tsx b/src/components/ai-edition/v4/V4Timeline.geometry.test.tsx
index f3a067bca..d237428f5 100644
--- a/src/components/ai-edition/v4/V4Timeline.geometry.test.tsx
+++ b/src/components/ai-edition/v4/V4Timeline.geometry.test.tsx
@@ -64,7 +64,7 @@ function clip(startSec: number, endSec: number) {
}
/** The asset every clip above points at. No `cameraTrack`: this recording has no webcam,
- * which is what the Full Camera button is gated on. */
+ * which is what Add Full Camera is gated on. */
const NO_CAMERA_ASSET = { id: "a1", label: "rec", durationSec: TOTAL_SEC };
/** By default one 30-minute clip carrying a single one-second annotation. */
@@ -221,29 +221,11 @@ describe("V4Timeline create-from-toolbar", () => {
expect(durationOf(tl)).toBeCloseTo(0.25, 3);
});
- // #353. A camera-fullscreen region grows the webcam overlay, so with no webcam on the
- // timeline it renders nothing in the preview and nothing in the export — the region is
- // stored and forgotten. `addCameraFullscreen` now refuses to write one; the button says
- // so before it is clicked instead of looking like it worked.
- it("disables Add Full Camera when no clip on the timeline has a camera", () => {
- renderTimeline();
- expect(screen.getByTitle("buttons.addCameraFullscreen")).toBeDisabled();
- });
-
- it("enables Add Full Camera as soon as a clip's asset carries one", () => {
- renderTimeline(undefined, undefined, [
- {
- ...NO_CAMERA_ASSET,
- cameraTrack: { sourcePath: "/tmp/cam.webm", startMs: 0, offsetMs: 0, visible: true },
- },
- ]);
- expect(screen.getByTitle("buttons.addCameraFullscreen")).toBeEnabled();
- });
-
- // The disabled button is only half the promise: an empty lane advertises the shortcut
- // that fills it, so on a camera-less project it was still inviting a `C` press that
- // `addCameraFullscreen` now refuses. It borrows the Layout pane's "No Webcam" wording
- // instead, so the two surfaces agree about the same project.
+ // The toolbar button is gone, but Add Full Camera is still reachable via the `C`
+ // shortcut, and an empty lane advertises it — so on a camera-less project it was
+ // still inviting a `C` press that `addCameraFullscreen` refuses (#353). It borrows
+ // the Layout pane's "No Webcam" wording instead, so the two surfaces agree about
+ // the same project.
it("does not advertise the C shortcut on a lane that cannot be filled", () => {
renderTimeline();
expect(screen.getByText("layout.noWebcam")).toBeInTheDocument();
diff --git a/src/components/ai-edition/v4/V4Timeline.tsx b/src/components/ai-edition/v4/V4Timeline.tsx
index 493f17d5c..a6300bb47 100644
--- a/src/components/ai-edition/v4/V4Timeline.tsx
+++ b/src/components/ai-edition/v4/V4Timeline.tsx
@@ -431,9 +431,9 @@ export function V4Timeline({
const clips = tl.clips;
// A camera-fullscreen region grows the webcam overlay, so on a project with no webcam
// it renders nothing in the preview and nothing in the export. `addCameraFullscreen`
- // refuses to write one (see useTimeline) — this makes the control say so before it is
- // clicked instead of looking like it worked. Same question, same helper as the Layout
- // pane: is a camera attached anywhere on this timeline?
+ // refuses to write one (see useTimeline) — this is why the empty lane's hint below
+ // swaps to "no webcam" instead of advertising the `C` shortcut. Same question, same
+ // helper as the Layout pane: is a camera attached anywhere on this timeline?
const hasAnyCamera = useMemo(() => hasAnyClipWithCamera(tl.assets, clips), [tl.assets, clips]);
const total = useMemo(
() =>
@@ -1359,17 +1359,6 @@ export function V4Timeline({
>
-
) : (
// Media is an ARRANGING surface: add, remove, reorder. Nothing here
@@ -1463,8 +1452,7 @@ export function V4Timeline({
{renderPills(zoomPills, t("hints.pressZoom"))}
{/* Advertising "Press C" on a project with no webcam invites a keystroke
- that `addCameraFullscreen` now refuses (#353). The toolbar button is
- already disabled; this keeps the lane from contradicting it. */}
+ that `addCameraFullscreen` now refuses (#353). */}
{renderPills(
cameraFullscreenPills,
hasAnyCamera ? t("hints.pressCameraFullscreen") : ts("layout.noWebcam"),
diff --git a/src/i18n/locales/ar/timeline.json b/src/i18n/locales/ar/timeline.json
index 4412a0a0b..e434620eb 100644
--- a/src/i18n/locales/ar/timeline.json
+++ b/src/i18n/locales/ar/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "تفعيل التركيز التلقائي لجميع التكبيرات (الكاميرا تتبع المؤشر)",
"addTrim": "إضافة قص (T)",
"addAnnotation": "إضافة شرح (A)",
- "addSpeed": "إضافة سرعة (S)",
- "addCameraFullscreen": "إضافة كاميرا كاملة الشاشة (C)"
+ "addSpeed": "إضافة سرعة (S)"
},
"hints": {
"pressZoom": "اضغط Z لإضافة تكبير",
diff --git a/src/i18n/locales/en/timeline.json b/src/i18n/locales/en/timeline.json
index c41966115..cd15921ef 100644
--- a/src/i18n/locales/en/timeline.json
+++ b/src/i18n/locales/en/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "Auto-Focus all zooms (camera follows the cursor)",
"addTrim": "Add Trim (T)",
"addAnnotation": "Add Annotation (A)",
- "addSpeed": "Add Speed (S)",
- "addCameraFullscreen": "Add Full Camera (C)"
+ "addSpeed": "Add Speed (S)"
},
"hints": {
"pressZoom": "Press Z to add zoom",
diff --git a/src/i18n/locales/es/timeline.json b/src/i18n/locales/es/timeline.json
index 989289e00..c05eebf89 100644
--- a/src/i18n/locales/es/timeline.json
+++ b/src/i18n/locales/es/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "Activar enfoque automático para todos los zooms (la cámara sigue el cursor)",
"addTrim": "Agregar recorte (T)",
"addAnnotation": "Agregar anotación (A)",
- "addSpeed": "Agregar velocidad (S)",
- "addCameraFullscreen": "Agregar cámara a pantalla completa (C)"
+ "addSpeed": "Agregar velocidad (S)"
},
"hints": {
"pressZoom": "Presiona Z para agregar zoom",
diff --git a/src/i18n/locales/fr/timeline.json b/src/i18n/locales/fr/timeline.json
index a35b8858a..3147db21d 100644
--- a/src/i18n/locales/fr/timeline.json
+++ b/src/i18n/locales/fr/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "Activer la mise au point automatique pour tous les zooms (la caméra suit le curseur)",
"addTrim": "Ajouter une coupe (T)",
"addAnnotation": "Ajouter une annotation (A)",
- "addSpeed": "Ajouter une vitesse (S)",
- "addCameraFullscreen": "Ajouter Caméra plein écran (C)"
+ "addSpeed": "Ajouter une vitesse (S)"
},
"hints": {
"pressZoom": "Appuyez sur Z pour ajouter un zoom",
diff --git a/src/i18n/locales/it/timeline.json b/src/i18n/locales/it/timeline.json
index 09bb116ee..468764831 100644
--- a/src/i18n/locales/it/timeline.json
+++ b/src/i18n/locales/it/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "Attiva la messa a fuoco automatica per tutti gli zoom (la fotocamera segue il cursore)",
"addTrim": "Aggiungi taglio (T)",
"addAnnotation": "Aggiungi annotazione (A)",
- "addSpeed": "Aggiungi velocità (S)",
- "addCameraFullscreen": "Aggiungi Camera a schermo intero (C)"
+ "addSpeed": "Aggiungi velocità (S)"
},
"hints": {
"pressZoom": "Premi Z per aggiungere zoom",
diff --git a/src/i18n/locales/ja-JP/timeline.json b/src/i18n/locales/ja-JP/timeline.json
index 68911ba91..7ebcc6b36 100644
--- a/src/i18n/locales/ja-JP/timeline.json
+++ b/src/i18n/locales/ja-JP/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "すべてのズームでオートフォーカスをオンにする(カメラがカーソルに追従)",
"addTrim": "トリムを追加 (T)",
"addAnnotation": "注釈を追加 (A)",
- "addSpeed": "再生速度を追加 (S)",
- "addCameraFullscreen": "フルスクリーンカメラを追加 (C)"
+ "addSpeed": "再生速度を追加 (S)"
},
"hints": {
"pressZoom": "Zキーを押してズームを追加",
diff --git a/src/i18n/locales/ko-KR/timeline.json b/src/i18n/locales/ko-KR/timeline.json
index 8a100ee6d..986d173ce 100644
--- a/src/i18n/locales/ko-KR/timeline.json
+++ b/src/i18n/locales/ko-KR/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "모든 줌에 자동 초점 켜기 (카메라가 커서를 따라갑니다)",
"addTrim": "트림 추가 (T)",
"addAnnotation": "주석 추가 (A)",
- "addSpeed": "속도 추가 (S)",
- "addCameraFullscreen": "전체 화면 카메라 추가 (C)"
+ "addSpeed": "속도 추가 (S)"
},
"hints": {
"pressZoom": "Z를 눌러 줌 추가",
diff --git a/src/i18n/locales/pt-BR/timeline.json b/src/i18n/locales/pt-BR/timeline.json
index 5359feba9..ed9c42bd7 100644
--- a/src/i18n/locales/pt-BR/timeline.json
+++ b/src/i18n/locales/pt-BR/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "Ativar foco automático para todos os zooms (a câmera segue o cursor)",
"addTrim": "Adicionar Recorte (T)",
"addAnnotation": "Adicionar Anotação (A)",
- "addSpeed": "Adicionar Velocidade (S)",
- "addCameraFullscreen": "Adicionar Câmera em Tela Cheia (C)"
+ "addSpeed": "Adicionar Velocidade (S)"
},
"hints": {
"pressZoom": "Pressione Z para adicionar zoom",
diff --git a/src/i18n/locales/ru/timeline.json b/src/i18n/locales/ru/timeline.json
index 387086953..9ce1261fb 100644
--- a/src/i18n/locales/ru/timeline.json
+++ b/src/i18n/locales/ru/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "Включить автофокус для всех зумов (камера следует за курсором)",
"addTrim": "Добавить обрезку (T)",
"addAnnotation": "Добавить аннотацию (A)",
- "addSpeed": "Изменить скорость (S)",
- "addCameraFullscreen": "Добавить камеру на весь экран (C)"
+ "addSpeed": "Изменить скорость (S)"
},
"hints": {
"pressZoom": "Нажмите Z для добавления масштабирования",
diff --git a/src/i18n/locales/tr/timeline.json b/src/i18n/locales/tr/timeline.json
index d5a531f3e..c56c0613b 100644
--- a/src/i18n/locales/tr/timeline.json
+++ b/src/i18n/locales/tr/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "Tüm yakınlaştırmalarda Otomatik Odağı aç (kamera imleci takip eder)",
"addTrim": "Kırpma Ekle (T)",
"addAnnotation": "Açıklama Ekle (A)",
- "addSpeed": "Hız Ekle (S)",
- "addCameraFullscreen": "Tam Ekran Kamera Ekle (C)"
+ "addSpeed": "Hız Ekle (S)"
},
"hints": {
"pressZoom": "Yakınlaştırma eklemek için Z tuşuna basın",
diff --git a/src/i18n/locales/vi/timeline.json b/src/i18n/locales/vi/timeline.json
index 1d963e585..fe6011b27 100644
--- a/src/i18n/locales/vi/timeline.json
+++ b/src/i18n/locales/vi/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "Bật lấy nét tự động cho tất cả các thu phóng (máy ảnh theo dõi con trỏ)",
"addTrim": "Thêm Cắt (T)",
"addAnnotation": "Thêm Chú thích (A)",
- "addSpeed": "Thêm Tốc độ (S)",
- "addCameraFullscreen": "Thêm Camera Toàn màn hình (C)"
+ "addSpeed": "Thêm Tốc độ (S)"
},
"hints": {
"pressZoom": "Nhấn Z để thêm thu phóng",
diff --git a/src/i18n/locales/zh-CN/timeline.json b/src/i18n/locales/zh-CN/timeline.json
index 1451e6d31..bd405fa89 100644
--- a/src/i18n/locales/zh-CN/timeline.json
+++ b/src/i18n/locales/zh-CN/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "为所有缩放开启自动对焦(摄像头跟随光标)",
"addTrim": "添加剪辑 (T)",
"addAnnotation": "添加标注 (A)",
- "addSpeed": "添加速度 (S)",
- "addCameraFullscreen": "添加全屏摄像头 (C)"
+ "addSpeed": "添加速度 (S)"
},
"hints": {
"pressZoom": "按 Z 添加缩放",
diff --git a/src/i18n/locales/zh-TW/timeline.json b/src/i18n/locales/zh-TW/timeline.json
index 7f4ba9874..6692ad24a 100644
--- a/src/i18n/locales/zh-TW/timeline.json
+++ b/src/i18n/locales/zh-TW/timeline.json
@@ -8,8 +8,7 @@
"autoFocusAllOff": "為所有縮放開啟自動對焦(攝影機跟隨游標)",
"addTrim": "新增剪輯 (T)",
"addAnnotation": "新增標註 (A)",
- "addSpeed": "新增速度 (S)",
- "addCameraFullscreen": "新增全螢幕攝影機 (C)"
+ "addSpeed": "新增速度 (S)"
},
"hints": {
"pressZoom": "按 Z 新增縮放",
diff --git a/src/lib/ai-edition/store/useTimeline.ts b/src/lib/ai-edition/store/useTimeline.ts
index 7823459ec..67f2ecdfb 100644
--- a/src/lib/ai-edition/store/useTimeline.ts
+++ b/src/lib/ai-edition/store/useTimeline.ts
@@ -407,9 +407,9 @@ export function useTimeline() {
// a missing `webcamRect`) and nothing in the export — it just sits in
// `legacyEditor.cameraFullscreenRegions` forever. The agent's `addCameraFullscreen`
// tool already refuses this and says why (electron/ai-edition/agent-tools.ts,
- // `noCameraUnderSpan`); the gate lives HERE rather than at each button so both UI
- // entry points — the toolbar and the `C` shortcut — and any future one are covered
- // by construction. `hasAnyClipWithCamera` is the consolidated answer to "does this
+ // `noCameraUnderSpan`); the gate lives HERE rather than at each caller so the `C`
+ // shortcut and any future entry point are covered by construction.
+ // `hasAnyClipWithCamera` is the consolidated answer to "does this
// project have a camera at all", used the same way by the Layout pane.
const addCameraFullscreen = useCallback(
async (durationSec = DEFAULT_NEW_REGION_SEC) => {