From 92b5a30df570164244442398a1e754b16bcb5221 Mon Sep 17 00:00:00 2001
From: ForgQi <34411314+ForgQi@users.noreply.github.com>
Date: Mon, 29 Sep 2025 03:18:21 +0800
Subject: [PATCH] Add streamer pause/resume feature and UI updates
Introduces a pause/resume button for streamers in the UI and backend, including API endpoint and status handling. Refactors streamer status display, updates related TypeScript interfaces, and improves modal forms. Also updates @douyinfe/semi-ui and related dependencies to v2.86.0, and bumps workspace version to 1.1.10. Minor logging and trait changes in Rust backend for improved clarity and error handling.
---
Cargo.lock | 4 +-
Cargo.toml | 2 +-
app/(app)/streamers/page.tsx | 66 +++++---
app/lib/api-streamer.ts | 3 +-
app/ui/OverrideModal.tsx | 6 -
app/ui/StreamerActions/PauseButton.tsx | 52 ++++++
app/ui/TemplateModal.tsx | 6 +
crates/biliup-cli/src/server/api/endpoints.rs | 59 ++++++-
.../biliup-cli/src/server/common/download.rs | 14 +-
crates/biliup-cli/src/server/common/upload.rs | 10 +-
.../biliup-cli/src/server/core/downloader.rs | 2 +-
.../core/downloader/ffmpeg_downloader.rs | 4 +-
.../server/core/downloader/stream_gears.rs | 2 +-
crates/biliup-cli/src/server/core/monitor.rs | 5 +-
.../src/server/infrastructure/context.rs | 5 +-
crates/biliup-cli/src/server/router.rs | 11 +-
crates/biliup/src/uploader/credential.rs | 8 +-
crates/stream-gears/src/danmaku.rs | 4 +-
crates/stream-gears/src/server.rs | 3 +-
package-lock.json | 150 +++++++++---------
package.json | 2 +-
21 files changed, 270 insertions(+), 148 deletions(-)
create mode 100644 app/ui/StreamerActions/PauseButton.tsx
diff --git a/Cargo.lock b/Cargo.lock
index 55ca2f7..a44839e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -395,7 +395,7 @@ dependencies = [
[[package]]
name = "biliup-cli"
-version = "1.1.9"
+version = "1.1.10"
dependencies = [
"async-channel",
"async-trait",
@@ -3641,7 +3641,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "stream-gears"
-version = "1.1.9"
+version = "1.1.10"
dependencies = [
"async-channel",
"async-trait",
diff --git a/Cargo.toml b/Cargo.toml
index 30c2188..77e7727 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,7 @@ members = [
resolver = "3"
[workspace.package]
-version = "1.1.9"
+version = "1.1.10"
[workspace.dependencies]
serde = { version = "1.0", features = ["derive"] }
diff --git a/app/(app)/streamers/page.tsx b/app/(app)/streamers/page.tsx
index 4970889..54bda31 100644
--- a/app/(app)/streamers/page.tsx
+++ b/app/(app)/streamers/page.tsx
@@ -1,21 +1,21 @@
'use client'
import {
- Layout,
- Nav,
- Button,
- Tag,
- Typography,
- Popconfirm,
- Notification,
- Card,
+ Layout,
+ Nav,
+ Button,
+ Tag,
+ Typography,
+ Popconfirm,
+ Notification,
+ Card, Dropdown,
} from '@douyinfe/semi-ui'
import {
- IconHelpCircle,
- IconPlusCircle,
- IconVideoListStroked,
- IconEdit2Stroked,
- IconDeleteStroked,
- IconWrench,
+ IconHelpCircle,
+ IconPlusCircle,
+ IconVideoListStroked,
+ IconEdit2Stroked,
+ IconDeleteStroked,
+ IconWrench, IconTreeTriangleDown, IconPause, IconPlay,
} from '@douyinfe/semi-icons'
import { List, ButtonGroup } from '@douyinfe/semi-ui'
import React, { useState } from 'react'
@@ -24,6 +24,7 @@ import TemplateModal from '../../ui/TemplateModal'
import OverrideModal from '../../ui/OverrideModal'
import { LiveStreamerEntity, put, requestDelete, sendRequest } from '../../lib/api-streamer'
import useSWRMutation from 'swr/mutation'
+import {PauseButton} from "@/app/ui/StreamerActions/PauseButton";
export default function Home() {
const { Header, Content } = Layout
@@ -54,25 +55,28 @@ export default function Home() {
return values
}
const data: LiveStreamerEntity[] | undefined = streamers?.map(live => {
- let status
+ let statusTag
switch (live.status) {
case 'Working':
- status = 直播中
+ statusTag = 直播中
break
case 'Idle':
- status = 空闲
+ statusTag = 空闲
break
case 'Pending':
- status = 未知
+ statusTag = 等待下载
break
case 'Inspecting':
- status = 检测/上传中
+ statusTag = 检测/上传中
break
case 'OutOfSchedule':
- status = 非录播时间
+ statusTag = 非录播时间
+ break
+ case 'Pause':
+ statusTag = 暂停中
break
}
- return { ...handleEntityPostprocessor(live), status }
+ return { ...handleEntityPostprocessor(live), statusTag }
})
const handleOk = async (values: any) => {
@@ -96,6 +100,7 @@ export default function Home() {
const handleUpdate = async (values: any) => {
console.log(values);
delete values.status
+ delete values.statusTag
if (values?.postprocessor) {
values.postprocessor = values.postprocessor.map(
({ cmd, value }: { cmd: string; value: string }) => (cmd === 'rm' ? 'rm' : { [cmd]: value })
@@ -112,6 +117,7 @@ export default function Home() {
throw e
}
}
+
return (
<>
- {item.status}
+ {item.statusTag}
}>
-
- }>
-
+
}>
+
+
+
+
+ }>
+
+
+
+ } trigger="click" position="bottomRight">
+ }>
+
diff --git a/app/lib/api-streamer.ts b/app/lib/api-streamer.ts
index aeed2ee..7961926 100644
--- a/app/lib/api-streamer.ts
+++ b/app/lib/api-streamer.ts
@@ -100,7 +100,8 @@ export interface LiveStreamerEntity {
split_time?: number;
split_size?: number;
upload_id?: number;
- status?: string | React.ReactNode;
+ status?: string;
+ statusTag?: React.ReactNode;
format?: string;
time_range?: string | Date[];
excluded_keywords?: string[];
diff --git a/app/ui/OverrideModal.tsx b/app/ui/OverrideModal.tsx
index 3a5e804..8aaee1c 100644
--- a/app/ui/OverrideModal.tsx
+++ b/app/ui/OverrideModal.tsx
@@ -222,12 +222,6 @@ const OverrideModal: React.FC = ({ children, entity, onOk })
stopValidateWithError={true}
/>
-
-
void;
+ onError?: (error: Error) => void;
+}
+
+// 暂停主播
+export const pauseStreamer = async (url: string, ) => {
+ const response = await fetch(API_BASE + url,
+ {
+ method: 'PUT',
+ // headers: {'Content-Type': 'application/json'},
+ }
+);
+ return response;
+};
+
+export const PauseButton: React.FC = ({
+ streamer,
+ onSuccess,
+ onError
+ }) => {
+ const { mutate } = useSWRConfig();
+
+ const { trigger: pauseTrigger } = useSWRMutation(
+ `/v1/streamers/${streamer.id}/pause`,
+ pauseStreamer
+ );
+
+ const handlePause = async () => {
+ try {
+ await pauseTrigger();
+ // 重新加载列表数据
+ await mutate('/v1/streamers');
+ onSuccess?.();
+ } catch (error) {
+ console.error('暂停失败:', error);
+ onError?.(error as Error);
+ }
+ };
+ console.log("????????????", streamer.status)
+ return (
+ : } theme="borderless" aria-label="暂停" />
+ );
+};
\ No newline at end of file
diff --git a/app/ui/TemplateModal.tsx b/app/ui/TemplateModal.tsx
index 415b00a..1ddc89a 100644
--- a/app/ui/TemplateModal.tsx
+++ b/app/ui/TemplateModal.tsx
@@ -155,6 +155,12 @@ const TemplateModal: React.FC = ({ children, entity, onOk })
rules={[{ required: true, message }]}
/>
+
+
,
+ State(pool): State,
+ State(workers): State>>>>,
+ Path(id): Path,
+) -> Result, Response> {
+ let option = workers
+ .read()
+ .unwrap()
+ .clone()
+ .into_iter()
+ .find(|worker| {
+ worker.live_streamer.id == id
+ });
+ if let Some(w) = option {
+ let manager = service_register.get_manager(&w.live_streamer.url).ok_or(AppError::Unknown).map_err(report_to_response)?;
+ let monitor = manager.ensure_monitor(pool.clone());
+ let worker_status = w.downloader_status.read().unwrap().clone();
+ let d = match worker_status {
+ WorkerStatus::Working(d) => {
+ *w.downloader_status.write().unwrap() = WorkerStatus::Pause;
+ Some(d.clone())
+ },
+ WorkerStatus::Pending => {
+ monitor.rooms_handle.toggle(w.clone()).await;
+ *w.downloader_status.write().unwrap() = WorkerStatus::Pause;
+ None
+ }
+ WorkerStatus::Idle => {
+ monitor.rooms_handle.toggle(w.clone()).await;
+ *w.downloader_status.write().unwrap() = WorkerStatus::Pause;
+ None
+ }
+ WorkerStatus::Pause => {
+ monitor.rooms_handle.toggle(w.clone()).await;
+ *w.downloader_status.write().unwrap() = WorkerStatus::Idle;
+ None
+ }
+ };
+
+ if let Some(d) = d {
+ d.stop().await.map_err(report_to_response)?;
+ }
+ info!(workers=?service_register.workers, "successfully pause live streamers");
+ }
+
+ Ok(Json(()))
+}
+
pub async fn get_configuration(
State(config): State>>,
) -> Result, Response> {
diff --git a/crates/biliup-cli/src/server/common/download.rs b/crates/biliup-cli/src/server/common/download.rs
index a509574..5341579 100644
--- a/crates/biliup-cli/src/server/common/download.rs
+++ b/crates/biliup-cli/src/server/common/download.rs
@@ -57,10 +57,6 @@ impl DownloadGuard {
impl Drop for DownloadGuard {
fn drop(&mut self) {
- // 确保状态更新和资源清理
- self.worker
- .change_status(Stage::Download, WorkerStatus::Idle);
-
// 异步清理任务
let danmaku = self.danmaku_client.clone();
let rooms_handle = self.rooms_handle.clone();
@@ -72,7 +68,13 @@ impl Drop for DownloadGuard {
error!("Error stopping danmaku client: {}", e);
}
}
- rooms_handle.toggle(worker).await
+ if let WorkerStatus::Pause = *worker.downloader_status.read().unwrap() {
+ } else {
+ // 确保状态更新和资源清理
+ worker
+ .change_status(Stage::Download, WorkerStatus::Idle);
+ rooms_handle.toggle(worker).await;
+ };
});
}
}
@@ -318,7 +320,7 @@ impl DownloadTask {
.unwrap_or_else(|| stream_info.suffix.clone());
// 创建录制器
let recorder = Recorder::new(
- streamer.filename_prefix,
+ streamer.filename_prefix.or(config.filename_prefix.clone()),
&streamer.remark,
&stream_info.streamer_info.title,
&suffix,
diff --git a/crates/biliup-cli/src/server/common/upload.rs b/crates/biliup-cli/src/server/common/upload.rs
index df4da47..e2f6520 100644
--- a/crates/biliup-cli/src/server/common/upload.rs
+++ b/crates/biliup-cli/src/server/common/upload.rs
@@ -151,13 +151,13 @@ async fn upload_single_file(file_path: &Path, context: &UploadContext) -> AppRes
let video_path = file_path;
info!(
- "{:?}",
+ "开始上传文件:{:?}",
video_path
.canonicalize()
.change_context(AppError::Unknown)?
.to_str()
);
- info!("{line:?}");
+ info!("线路选择:{line:?}");
let video_file = VideoFile::new(video_path).change_context(AppError::Unknown)?;
let total_size = video_file.total_size;
let file_name = video_file.file_name.clone();
@@ -274,11 +274,11 @@ pub async fn execute_postprocessor(video_paths: Vec, ctx: &Context) ->
let result = InsertFileItem {
file,
streamer_info_id: 0,
- }.insert(&pool).await;
+ }.insert(&pool).await;
info!(result=?result);
});
-
- p.as_path()
+
+ p.as_path()
}).collect();
process_video(&paths, &processor).await?;
}
diff --git a/crates/biliup-cli/src/server/core/downloader.rs b/crates/biliup-cli/src/server/core/downloader.rs
index 5f7d480..216ba08 100644
--- a/crates/biliup-cli/src/server/core/downloader.rs
+++ b/crates/biliup-cli/src/server/core/downloader.rs
@@ -134,7 +134,7 @@ pub trait Downloader: Send + Sync {
) -> AppResult;
/// 停止下载
- async fn stop(&self) -> Result<(), Box>;
+ async fn stop(&self) -> AppResult<()>;
/// 滚动保存(用于弹幕等)
///
diff --git a/crates/biliup-cli/src/server/core/downloader/ffmpeg_downloader.rs b/crates/biliup-cli/src/server/core/downloader/ffmpeg_downloader.rs
index 153350c..8c7f2b4 100644
--- a/crates/biliup-cli/src/server/core/downloader/ffmpeg_downloader.rs
+++ b/crates/biliup-cli/src/server/core/downloader/ffmpeg_downloader.rs
@@ -400,10 +400,10 @@ impl Downloader for FfmpegDownloader {
}
}
- async fn stop(&self) -> Result<(), Box> {
+ async fn stop(&self) -> AppResult<()> {
let mut handle = self.process_handle.write().await;
if let Some(child) = &mut *handle {
- child.kill().await?;
+ child.kill().await.change_context(AppError::Unknown)?;
Ok(())
} else {
Err(AppError::Custom("Process handle not found".to_string()).into())
diff --git a/crates/biliup-cli/src/server/core/downloader/stream_gears.rs b/crates/biliup-cli/src/server/core/downloader/stream_gears.rs
index b362ed3..44d87d0 100644
--- a/crates/biliup-cli/src/server/core/downloader/stream_gears.rs
+++ b/crates/biliup-cli/src/server/core/downloader/stream_gears.rs
@@ -149,7 +149,7 @@ impl Downloader for StreamGears {
}
/// 停止下载
- async fn stop(&self) -> Result<(), Box> {
+ async fn stop(&self) -> AppResult<()> {
// 仅发出取消信号并更新状态
// 如果底层下载函数不支持取消,这里不能真正中断正在进行的下载
self.token.cancel();
diff --git a/crates/biliup-cli/src/server/core/monitor.rs b/crates/biliup-cli/src/server/core/monitor.rs
index 23c15cd..171c197 100644
--- a/crates/biliup-cli/src/server/core/monitor.rs
+++ b/crates/biliup-cli/src/server/core/monitor.rs
@@ -31,9 +31,8 @@ async fn start_client(
loop {
// 获取下一个要检查的房间
if let Some(room) = rooms_handle.next().await {
- let ulr = room.get_streamer().url;
+ let url = room.get_streamer().url;
interval = room.get_config().event_loop_interval;
- info!("[{platform_name}] room: {ulr}");
let mut ctx = Context::new(room.clone(), Default::default(), pool.clone());
// 检查直播状态
match plugin.check_status(&mut ctx).await.unwrap() {
@@ -52,7 +51,7 @@ async fn start_client(
continue
}
};
- info!("room: {ulr} is live -> {:?}", stream_info);
+ info!(url=url, "room: is live -> 开播了");
// 更新状态为等待中
room.change_status(Stage::Download, WorkerStatus::Pending);
stream_info.streamer_info = insert;
diff --git a/crates/biliup-cli/src/server/infrastructure/context.rs b/crates/biliup-cli/src/server/infrastructure/context.rs
index bd9f39a..6ae1d0a 100644
--- a/crates/biliup-cli/src/server/infrastructure/context.rs
+++ b/crates/biliup-cli/src/server/infrastructure/context.rs
@@ -147,7 +147,7 @@ pub enum Stage {
}
/// 工作器状态枚举
-#[derive(Default)]
+#[derive(Default, Clone)]
pub enum WorkerStatus {
/// 正在工作
Working(Arc),
@@ -156,6 +156,8 @@ pub enum WorkerStatus {
/// 空闲状态(默认)
#[default]
Idle,
+ /// 下载暂停中
+ Pause
}
// 简单 Debug:打印状态名,忽略内部 downloader
@@ -165,6 +167,7 @@ impl fmt::Debug for WorkerStatus {
WorkerStatus::Working(_) => "Working",
WorkerStatus::Pending => "Pending",
WorkerStatus::Idle => "Idle",
+ WorkerStatus::Pause => "Pause"
};
f.write_str(name)
}
diff --git a/crates/biliup-cli/src/server/router.rs b/crates/biliup-cli/src/server/router.rs
index 2ad62fd..37956d2 100644
--- a/crates/biliup-cli/src/server/router.rs
+++ b/crates/biliup-cli/src/server/router.rs
@@ -1,19 +1,13 @@
use crate::server::api::bilibili_endpoints::{
archive_pre_endpoint, get_myinfo_endpoint, get_proxy_endpoint,
};
-use crate::server::api::endpoints::{
- add_upload_streamer_endpoint, add_user_endpoint, delete_streamers_endpoint,
- delete_template_endpoint, delete_user_endpoint, get_configuration, get_qrcode, get_status,
- get_streamer_info, get_streamers_endpoint, get_upload_streamer_endpoint,
- get_upload_streamers_endpoint, get_users_endpoint, get_videos, login_by_qrcode,
- post_streamers_endpoint, post_uploads, put_configuration, put_streamers_endpoint,
-};
+use crate::server::api::endpoints::{add_upload_streamer_endpoint, add_user_endpoint, delete_streamers_endpoint, delete_template_endpoint, delete_user_endpoint, get_configuration, get_qrcode, get_status, get_streamer_info, get_streamers_endpoint, get_upload_streamer_endpoint, get_upload_streamers_endpoint, get_users_endpoint, get_videos, login_by_qrcode, pause_streamers_endpoint, post_streamers_endpoint, post_uploads, put_configuration, put_streamers_endpoint};
use crate::server::infrastructure::service_register::ServiceRegister;
use axum::Router;
use axum::body::Body;
use axum::http::Request;
use axum::response::IntoResponse;
-use axum::routing::{delete, get, post};
+use axum::routing::{delete, get, post, put};
use tower::ServiceExt;
use tower_http::services::ServeFile;
/// 创建应用程序路由
@@ -27,6 +21,7 @@ pub fn router(service_register: ServiceRegister) -> Router<()> {
.put(put_streamers_endpoint), // 更新主播
)
.route("/v1/streamers/{id}", delete(delete_streamers_endpoint)) // 删除主播
+ .route("/v1/streamers/{id}/pause", put(pause_streamers_endpoint)) // 删除主播
// 配置管理路由
.route(
"/v1/configuration",
diff --git a/crates/biliup/src/uploader/credential.rs b/crates/biliup/src/uploader/credential.rs
index 9ae1f3e..3f7c962 100644
--- a/crates/biliup/src/uploader/credential.rs
+++ b/crates/biliup/src/uploader/credential.rs
@@ -15,7 +15,7 @@ use rsa::{Pkcs1v15Encrypt, RsaPublicKey, pkcs8::DecodePublicKey};
use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
-use tracing::info;
+use tracing::{debug, info};
use url::Url;
// const APP_KEY: &str = "ae57252b0c09105d";
@@ -63,7 +63,7 @@ pub fn bilibili_from_cookies(file: impl AsRef, proxy: Option<&str>) -> Res
pub fn bilibili_from_info(login_info: LoginInfo, proxy: Option<&str>) -> Result {
let client = Credential::new(proxy);
client.set_cookie(&login_info.cookie_info);
- info!("通过cookie登录");
+ debug!("通过cookie登录");
Ok(BiliBili {
client: client.0.client,
login_info,
@@ -85,7 +85,7 @@ pub async fn login_by_cookies(file: impl AsRef, proxy: Option<&str>) -> Re
serde_json::to_writer_pretty(std::io::BufWriter::new(&file), &new_info)?;
bilibili_from_info(new_info, proxy)
} else {
- info!("无需更新cookie");
+ debug!("无需更新cookie");
bilibili_from_info(login_info, proxy)
}
}
@@ -174,7 +174,7 @@ impl Credential {
_ => return Err(Kind::Custom(response.to_string())),
};
- info!("验证cookie");
+ debug!("验证cookie");
Ok(refresh)
}
diff --git a/crates/stream-gears/src/danmaku.rs b/crates/stream-gears/src/danmaku.rs
index a1fb5b4..f1f38d9 100644
--- a/crates/stream-gears/src/danmaku.rs
+++ b/crates/stream-gears/src/danmaku.rs
@@ -49,7 +49,7 @@ impl Downloader for DanmakuClient {
}
/// Stops the danmaku recording
- async fn stop(&self) -> Result<(), Box> {
+ async fn stop(&self) -> AppResult<()> {
let py_client = self.py_client.clone();
// Call the DanmakuClient's stop method (not the trait method)
tokio::task::spawn_blocking(move || {
@@ -59,7 +59,7 @@ impl Downloader for DanmakuClient {
Ok::<_, PyErr>(())
})
})
- .await??;
+ .await.change_context(AppError::Unknown)?.change_context(AppError::Unknown)?;
Ok(())
}
diff --git a/crates/stream-gears/src/server.rs b/crates/stream-gears/src/server.rs
index ea78fe0..3d938b0 100644
--- a/crates/stream-gears/src/server.rs
+++ b/crates/stream-gears/src/server.rs
@@ -72,7 +72,6 @@ impl DownloadPlugin for PyPlugin {
}
async fn check_status(&self, ctx: &mut Context) -> Result> {
- info!("Checking status");
match call_via_threads(self.plugin.clone(), &ctx.worker.live_streamer.url)
.await
.change_context(AppError::Unknown)?
@@ -250,7 +249,7 @@ pub fn stream_info_from_py(
// lt.to_object(py)
// }
// };self.update_headers(self.stream_headers)
-
+
Ok((
StreamInfoExt {
streamer_info: StreamerInfo {
diff --git a/package-lock.json b/package-lock.json
index c62cfd6..1bcd4dc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,7 +8,7 @@
"name": "my-app",
"version": "0.1.0",
"dependencies": {
- "@douyinfe/semi-ui": "^2.75.0",
+ "@douyinfe/semi-ui": "^2.86.0",
"artplayer": "^5.2.1",
"mpegts.js": "^1.8.0",
"next": "^14.2.26",
@@ -97,39 +97,39 @@
}
},
"node_modules/@douyinfe/semi-animation": {
- "version": "2.77.1",
- "resolved": "https://registry.npmjs.org/@douyinfe/semi-animation/-/semi-animation-2.77.1.tgz",
- "integrity": "sha512-Q1D7whvQe0D+mPov8hXeH/e1uR/iBhpGGcW1LCTL2pSVMEZEYGJLf2KeXTTiCIgRVWm0PRH3Sux7auJ64zg7vw==",
+ "version": "2.86.0",
+ "resolved": "https://registry.npmjs.org/@douyinfe/semi-animation/-/semi-animation-2.86.0.tgz",
+ "integrity": "sha512-+MerLT6TJnJSbTnKQ5Za1HwxiM7snhfMdg2IX/0KXxwFYhkHsnkj07krZBNKMKWDJpfG2qkb9z7KD/NQH7KL6w==",
"license": "MIT",
"dependencies": {
"bezier-easing": "^2.1.0"
}
},
"node_modules/@douyinfe/semi-animation-react": {
- "version": "2.77.1",
- "resolved": "https://registry.npmjs.org/@douyinfe/semi-animation-react/-/semi-animation-react-2.77.1.tgz",
- "integrity": "sha512-imELR02pufgGFkZURfTd9oBUtZPYhHvXv9WsYoRvEoBM9U7yzxrR6Fb/Lc3TH+WHVJ2oZHH2S0APS5t1MceEOw==",
+ "version": "2.86.0",
+ "resolved": "https://registry.npmjs.org/@douyinfe/semi-animation-react/-/semi-animation-react-2.86.0.tgz",
+ "integrity": "sha512-nThSOLD6iU8gyNALDYAsbXgcmM9eAJe7F1Sb5zvOi56cA4M52Wk50AuS9InAbGTJjzxNY7FkBu1KMepxXDHEIg==",
"license": "MIT",
"dependencies": {
- "@douyinfe/semi-animation": "2.77.1",
- "@douyinfe/semi-animation-styled": "2.77.1",
+ "@douyinfe/semi-animation": "2.86.0",
+ "@douyinfe/semi-animation-styled": "2.86.0",
"classnames": "^2.2.6"
}
},
"node_modules/@douyinfe/semi-animation-styled": {
- "version": "2.77.1",
- "resolved": "https://registry.npmjs.org/@douyinfe/semi-animation-styled/-/semi-animation-styled-2.77.1.tgz",
- "integrity": "sha512-FBRroqVJroel1CXmBgV58ulZHG2xUVInJF7k0FAag54noKKaToEobSxRjiTJ6JHne3ZDU1M6sBqpbzYJElFnPQ==",
+ "version": "2.86.0",
+ "resolved": "https://registry.npmjs.org/@douyinfe/semi-animation-styled/-/semi-animation-styled-2.86.0.tgz",
+ "integrity": "sha512-5x5WA8i1vuwb7rygScWmqxwgNggvpGd0rtDwAqBX8l5KoDSml2ikmR015w+SaoOD/UGwJB44IJ02UYYcxZw9kg==",
"license": "MIT"
},
"node_modules/@douyinfe/semi-foundation": {
- "version": "2.77.1",
- "resolved": "https://registry.npmjs.org/@douyinfe/semi-foundation/-/semi-foundation-2.77.1.tgz",
- "integrity": "sha512-DAXRy8ryLNzbKAiTAv+RrivGCoMU0asv2cO7PNV5aBq0ICB8XXn97FHyZo6Wb5NpqpyMhOaOr8Ro1bfpd0FeaA==",
+ "version": "2.86.0",
+ "resolved": "https://registry.npmjs.org/@douyinfe/semi-foundation/-/semi-foundation-2.86.0.tgz",
+ "integrity": "sha512-IX6Vzcen16u+Z1fbYPCAnZIqxfnAk7kI9CBJ9u6rZM8LIEP/HMYSEdMmCg8Cigw4GiSbjdlDfy6miy5tXWJmAQ==",
"license": "MIT",
"dependencies": {
- "@douyinfe/semi-animation": "2.77.1",
- "@douyinfe/semi-json-viewer-core": "2.77.1",
+ "@douyinfe/semi-animation": "2.86.0",
+ "@douyinfe/semi-json-viewer-core": "2.86.0",
"@mdx-js/mdx": "^3.0.1",
"async-validator": "^3.5.0",
"classnames": "^2.2.6",
@@ -145,9 +145,9 @@
}
},
"node_modules/@douyinfe/semi-icons": {
- "version": "2.77.1",
- "resolved": "https://registry.npmjs.org/@douyinfe/semi-icons/-/semi-icons-2.77.1.tgz",
- "integrity": "sha512-IbGqYzbjzCoSd+//HlO/Gn1c3XmbulQwGys+JgDfQhYIbPeGyhQfLk56Q7ku3vJGC8BGy7dUmR9MbeTf1UQGtw==",
+ "version": "2.86.0",
+ "resolved": "https://registry.npmjs.org/@douyinfe/semi-icons/-/semi-icons-2.86.0.tgz",
+ "integrity": "sha512-KEDlYYP1wdOqN28Ck0YcdCx7mSks8SRY4w4KKbXPaROzYNEyT2BRcJxwysMHfxL2IDfsroHrRPJsX9pnrmQqTg==",
"license": "MIT",
"dependencies": {
"classnames": "^2.2.6"
@@ -157,44 +157,44 @@
}
},
"node_modules/@douyinfe/semi-illustrations": {
- "version": "2.77.1",
- "resolved": "https://registry.npmjs.org/@douyinfe/semi-illustrations/-/semi-illustrations-2.77.1.tgz",
- "integrity": "sha512-FlESLOPaY0SadiSIFcP4gqJUk+CYkd4rHK6YP9bfjmU26v7h1S02H7pGLLV1lS0WnY4j0ad4zqRV9tbXFvba9g==",
+ "version": "2.86.0",
+ "resolved": "https://registry.npmjs.org/@douyinfe/semi-illustrations/-/semi-illustrations-2.86.0.tgz",
+ "integrity": "sha512-ZRgtgPor1X9lZP/8IOT4xZOmio+tWBUb9Sb2MAjTj52ZtJB6u4jz34y4TnoqRjoGRYWwNvOQmNjBk9NiHoAYkg==",
"license": "MIT",
"peerDependencies": {
"react": ">=16.0.0"
}
},
"node_modules/@douyinfe/semi-json-viewer-core": {
- "version": "2.77.1",
- "resolved": "https://registry.npmjs.org/@douyinfe/semi-json-viewer-core/-/semi-json-viewer-core-2.77.1.tgz",
- "integrity": "sha512-LOW+7ga2OzFIL9pGKftwHfl1kKLTV3x6Cs857iyvq9GIF/GHbAboiHcKUy2OZIHfy66zvP+Focs+yhfZG7IcZw==",
+ "version": "2.86.0",
+ "resolved": "https://registry.npmjs.org/@douyinfe/semi-json-viewer-core/-/semi-json-viewer-core-2.86.0.tgz",
+ "integrity": "sha512-Xk8CkQ/VKACUZfLg9D5vds9vy2WvWzI5ezioBNKRF5GPnonYeL6vwFz0rpzSL4dKdS17Ndg5KexWV4g9mExgLg==",
"license": "MIT",
"dependencies": {
"jsonc-parser": "^3.3.1"
}
},
"node_modules/@douyinfe/semi-theme-default": {
- "version": "2.77.1",
- "resolved": "https://registry.npmjs.org/@douyinfe/semi-theme-default/-/semi-theme-default-2.77.1.tgz",
- "integrity": "sha512-Rug75C7jjSqmCP2L2tBI0K4dnXuo4GardzwSzdSjxDkiaIXwOwR5KE0K1FRbKWkQ7xmxbyRu4S6Pff+CDEJ/lA==",
+ "version": "2.86.0",
+ "resolved": "https://registry.npmjs.org/@douyinfe/semi-theme-default/-/semi-theme-default-2.86.0.tgz",
+ "integrity": "sha512-l1zVriNXVxBribjTL7hGyiHrymum3UOPpiurWZdleK7oKWPVtkWdDh+cdVkDS/QynEY7P+m0zFCye1GbjNPkNg==",
"license": "MIT"
},
"node_modules/@douyinfe/semi-ui": {
- "version": "2.77.1",
- "resolved": "https://registry.npmjs.org/@douyinfe/semi-ui/-/semi-ui-2.77.1.tgz",
- "integrity": "sha512-eIy7kr9OleCwlNRby3VICSGScHM23Zt2u7TJpID68qN3WrfQowGaB4wQ/0k5bvpLzv463HQnVWFk5aak+v46yw==",
+ "version": "2.86.0",
+ "resolved": "https://registry.npmjs.org/@douyinfe/semi-ui/-/semi-ui-2.86.0.tgz",
+ "integrity": "sha512-UAwM3+qO25Zkvy3a+7Jk8xBt5/103eP/t9x2pqvRITLeP2XqIikXruXV3bSLO1HDlCt9VyORqxC9UEYFOutk5Q==",
"license": "MIT",
"dependencies": {
"@dnd-kit/core": "^6.0.8",
"@dnd-kit/sortable": "^7.0.2",
"@dnd-kit/utilities": "^3.2.1",
- "@douyinfe/semi-animation": "2.77.1",
- "@douyinfe/semi-animation-react": "2.77.1",
- "@douyinfe/semi-foundation": "2.77.1",
- "@douyinfe/semi-icons": "2.77.1",
- "@douyinfe/semi-illustrations": "2.77.1",
- "@douyinfe/semi-theme-default": "2.77.1",
+ "@douyinfe/semi-animation": "2.86.0",
+ "@douyinfe/semi-animation-react": "2.86.0",
+ "@douyinfe/semi-foundation": "2.86.0",
+ "@douyinfe/semi-icons": "2.86.0",
+ "@douyinfe/semi-illustrations": "2.86.0",
+ "@douyinfe/semi-theme-default": "2.86.0",
"async-validator": "^3.5.0",
"classnames": "^2.2.6",
"copy-text-to-clipboard": "^2.1.1",
@@ -414,15 +414,16 @@
"license": "MIT"
},
"node_modules/@mdx-js/mdx": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.0.tgz",
- "integrity": "sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz",
+ "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==",
"license": "MIT",
"dependencies": {
"@types/estree": "^1.0.0",
"@types/estree-jsx": "^1.0.0",
"@types/hast": "^3.0.0",
"@types/mdx": "^2.0.0",
+ "acorn": "^8.0.0",
"collapse-white-space": "^2.0.0",
"devlop": "^1.0.0",
"estree-util-is-identifier-name": "^3.0.0",
@@ -1895,9 +1896,9 @@
}
},
"node_modules/decode-named-character-reference": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz",
- "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz",
+ "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==",
"license": "MIT",
"dependencies": {
"character-entities": "^2.0.0"
@@ -4055,9 +4056,9 @@
}
},
"node_modules/lottie-web": {
- "version": "5.12.2",
- "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.12.2.tgz",
- "integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==",
+ "version": "5.13.0",
+ "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.13.0.tgz",
+ "integrity": "sha512-+gfBXl6sxXMPe8tKQm7qzLnUy5DUPJPKIyRHwtpCpyUEYjHYRJC/5gjUvdkuO2c3JllrPtHXH5UJJK8LRYl5yQ==",
"license": "MIT"
},
"node_modules/markdown-extensions": {
@@ -5647,9 +5648,9 @@
}
},
"node_modules/property-information": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.0.0.tgz",
- "integrity": "sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
+ "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==",
"license": "MIT",
"funding": {
"type": "github",
@@ -5862,9 +5863,9 @@
}
},
"node_modules/recma-jsx": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.0.tgz",
- "integrity": "sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz",
+ "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==",
"license": "MIT",
"dependencies": {
"acorn-jsx": "^5.0.0",
@@ -5876,6 +5877,9 @@
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
+ },
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/recma-parse": {
@@ -5992,9 +5996,9 @@
}
},
"node_modules/remark-mdx": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.0.tgz",
- "integrity": "sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz",
+ "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==",
"license": "MIT",
"dependencies": {
"mdast-util-mdx": "^3.0.0",
@@ -6022,9 +6026,9 @@
}
},
"node_modules/remark-rehype": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.1.tgz",
- "integrity": "sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==",
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz",
+ "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==",
"license": "MIT",
"dependencies": {
"@types/hast": "^3.0.0",
@@ -6415,12 +6419,12 @@
}
},
"node_modules/source-map": {
- "version": "0.7.4",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
- "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+ "version": "0.7.6",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
+ "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
"license": "BSD-3-Clause",
"engines": {
- "node": ">= 8"
+ "node": ">= 12"
}
},
"node_modules/source-map-js": {
@@ -6653,18 +6657,18 @@
}
},
"node_modules/style-to-js": {
- "version": "1.1.16",
- "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz",
- "integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==",
+ "version": "1.1.17",
+ "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz",
+ "integrity": "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==",
"license": "MIT",
"dependencies": {
- "style-to-object": "1.0.8"
+ "style-to-object": "1.0.9"
}
},
"node_modules/style-to-object": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz",
- "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==",
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz",
+ "integrity": "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==",
"license": "MIT",
"dependencies": {
"inline-style-parser": "0.2.4"
@@ -7108,9 +7112,9 @@
}
},
"node_modules/vfile-message": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz",
- "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz",
+ "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==",
"license": "MIT",
"dependencies": {
"@types/unist": "^3.0.0",
diff --git a/package.json b/package.json
index bb06ea1..d801818 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,7 @@
"lint": "next lint"
},
"dependencies": {
- "@douyinfe/semi-ui": "^2.75.0",
+ "@douyinfe/semi-ui": "^2.86.0",
"artplayer": "^5.2.1",
"mpegts.js": "^1.8.0",
"next": "^14.2.26",