lv vor 2 Wochen
Ursprung
Commit
76cf7851d4
8 geänderte Dateien mit 66 neuen und 35 gelöschten Zeilen
  1. 1 0
      build.bat
  2. 4 0
      src-tauri/.gitignore
  3. 7 0
      src-tauri/src/recording.rs
  4. 4 2
      src-tauri/tauri.conf.json
  5. 1 0
      src/App.css
  6. 33 32
      src/App.tsx
  7. 9 0
      src/components/TaskItem.tsx
  8. 7 1
      src/main.tsx

+ 1 - 0
build.bat

@@ -0,0 +1 @@
+pnpm tauri build --target x86_64-pc-windows-msvc

+ 4 - 0
src-tauri/.gitignore

@@ -6,3 +6,7 @@
 # will have schema files for capabilities auto-completion
 /gen/schemas
 /resources/ffmpeg
+/*.exe
+/*.zip
+/*.7z
+/*.rar

+ 7 - 0
src-tauri/src/recording.rs

@@ -353,6 +353,13 @@ fn spawn_ffmpeg(
     // 把要执行的命令打到日志,方便用户手工复现调试
     eprintln!("[recording] spawning: ffmpeg{}", format_args_for_log(&cmd));
 
+    #[cfg(target_os = "windows")]
+    {
+        // CREATE_NO_WINDOW = 0x08000000,抑制 ffmpeg 子进程的 console 窗口
+        const CREATE_NO_WINDOW: u32 = 0x0800_0000;
+        cmd.creation_flags(CREATE_NO_WINDOW);
+    }
+
     let mut child = cmd.spawn().map_err(|e| {
         format!("启动 ffmpeg 失败(请确认 src-tauri/resources/ffmpeg/ 下已放置 ffmpeg.exe): {e}")
     })?;

+ 4 - 2
src-tauri/tauri.conf.json

@@ -35,7 +35,9 @@
   },
   "bundle": {
     "active": true,
-    "targets": "all",
+    "targets": [
+      "msi"
+    ],
     "icon": [
       "icons/32x32.png",
       "icons/128x128.png",
@@ -44,7 +46,7 @@
       "icons/icon.ico"
     ],
     "resources": [
-      "resources/ffmpeg/*"
+      "resources/ffmpeg"
     ]
   }
 }

+ 1 - 0
src/App.css

@@ -113,6 +113,7 @@
 html,
 body,
 #root {
+  background: #1f1f3f;
   height: 100%;
   margin: 0;
 }

+ 33 - 32
src/App.tsx

@@ -3,8 +3,8 @@ import { invoke } from "@tauri-apps/api/core";
 import { listen, type UnlistenFn } from "@tauri-apps/api/event";
 import { getCurrentWindow } from "@tauri-apps/api/window";
 import { WebviewWindow } from "@tauri-apps/api/webviewWindow";
-import { openUrl, revealItemInDir } from "@tauri-apps/plugin-opener";
-import { Button, ConfigProvider, Divider, InputNumber, Layout, Menu, notification, Space, theme, Tooltip } from "antd";
+import { revealItemInDir } from "@tauri-apps/plugin-opener";
+import { Button, Divider, InputNumber, Layout, Menu, notification, Space, theme, Tooltip } from "antd";
 import {
   countPendingTasks,
   listPendingTasks,
@@ -44,8 +44,10 @@ import {
   LinkOutlined,
   LoadingOutlined,
   MinusOutlined,
+  OrderedListOutlined,
   PictureOutlined,
   PlayCircleFilled,
+  PlusOutlined,
   StopOutlined,
   VideoCameraOutlined,
 } from "@ant-design/icons";
@@ -78,13 +80,13 @@ async function loadInWebview(taskId: string, url: string) {
 }
 
 /** 点条目右侧图标:调系统浏览器打开 */
-async function openInBrowser(url: string) {
-  try {
-    await openUrl(url);
-  } catch (e) {
-    console.error("打开系统浏览器失败:", e);
-  }
-}
+// async function openInBrowser(url: string) {
+//   try {
+//     await openUrl(url);
+//   } catch (e) {
+//     console.error("打开系统浏览器失败:", e);
+//   }
+// }
 
 function App() {
   // 当前激活的任务 id(仅用于左栏视觉高亮)
@@ -206,7 +208,8 @@ function App() {
       const pending = await countPendingTasks().catch(() => 0);
       const list = await reloadTasks();
       if (pending === 0 && list.length === 0) {
-        await openImportWindow();
+        setTimeout(() =>
+          openImportWindow(), 500);
       }
     })();
     // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -569,8 +572,8 @@ function App() {
     token: { colorBgContainer },
   } = theme.useToken();
 
-  const [statusColor, setStatusColor] = useState("#888");
-  const [statusText, setStatusText] = useState("请选择任务");
+  const [statusColor] = useState("#888");
+  const [statusText] = useState("请选择任务");
 
   // 当前窗口句柄,用于自定义标题栏的最小化 / 关闭
   const appWindow = useMemo(() => getCurrentWindow(), []);
@@ -789,19 +792,24 @@ function App() {
       </Header>
       <Layout>
         <Sider className="select-none" collapsible collapsed={collapsed} onCollapse={(c) => handleCollaspsed(c)} width={180} style={{ background: colorBgContainer }}>
-          <Menu
-            mode="inline"
-            defaultSelectedKeys={[activeId || '']}
-            selectedKeys={[activeId || '']}
-            style={{ height: '100%', borderInlineEnd: 0 }}
-            onClick={handleSelectTask}
+          <div className="h-full w-full flex-row">
+            <div className="flex justify-between items-center text-md pl-1 font-bold text-white"><OrderedListOutlined />{collapsed ? '' : '所有任务'}<Button icon={<PlusOutlined />} onClick={openImportWindow} /> </div>
+            <div className="flex-1 overflow-y-auto">
+              <Menu
+                mode="vertical"
+                defaultSelectedKeys={[activeId || '']}
+                selectedKeys={[activeId || '']}
+                style={{ borderInlineEnd: 0, height: '100%' }}
+                onClick={handleSelectTask}
 
-          >
-            {tasks.map((t) => <Menu.Item icon={<LinkOutlined />} key={t.id}>
-              {t.id}
-            </Menu.Item>
-            )}
-          </Menu>
+              >
+                {tasks.map((t) => <Menu.Item icon={<LinkOutlined />} key={t.id}>
+                  {t.id}
+                </Menu.Item>
+                )}
+              </Menu>
+            </div>
+          </div>
         </Sider>
         <Layout className="flex flex-row">
           <Content className="w-full m-0 p-1 flex-1" />
@@ -819,11 +827,4 @@ function App() {
 
 
 
-export default function Main() {
-  return <ConfigProvider theme={{
-    // 1. Use dark algorithm alone
-    algorithm: [theme.darkAlgorithm, theme.compactAlgorithm]
-  }}>
-    <App />
-  </ ConfigProvider>
-};
+export default App;

+ 9 - 0
src/components/TaskItem.tsx

@@ -0,0 +1,9 @@
+import { DeleteOutlined } from '@ant-design/icons'
+import { type Task } from '../lib/tasks'
+export default function TaskItem({ task, onClick }: { task: Task, onClick: () => void }) {
+
+    return <div className="w-full flex flex-row items-center" onClick={onClick}>
+        <span className="flex-1">{task.id}</span>
+        <DeleteOutlined />
+    </div>
+}

+ 7 - 1
src/main.tsx

@@ -1,9 +1,15 @@
 import React from "react";
 import ReactDOM from "react-dom/client";
 import App from "./App";
+import { ConfigProvider, theme } from "antd";
 
 ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
   <React.StrictMode>
-    <App />
+    <ConfigProvider theme={{
+      // 1. Use dark algorithm alone
+      algorithm: [theme.darkAlgorithm, theme.compactAlgorithm]
+    }}>
+      <App />
+    </ConfigProvider>
   </React.StrictMode>,
 );