From 79e5d3abb64f9e9a0ac092d7d7bef28797f63a42 Mon Sep 17 00:00:00 2001 From: Vaica <94612053+zqlit@users.noreply.github.com> Date: Mon, 22 Jun 2026 17:21:57 +0800 Subject: [PATCH] 1721 --- themes/Ying/assets/css/main.css | 11 +++++++++++ themes/Ying/layouts/shortcodes/video.html | 10 +++++++++- write-server/src/lib/bot/poll.ts | 16 ++++++++++++---- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/themes/Ying/assets/css/main.css b/themes/Ying/assets/css/main.css index 333c1889..0a9097c2 100644 --- a/themes/Ying/assets/css/main.css +++ b/themes/Ying/assets/css/main.css @@ -5842,6 +5842,17 @@ a.link-card:hover .link-card-arrow { color: #9ca3af; } +/* GIF 模式:自动播放、循环、无控制栏 */ +.video-player.gif-mode { + cursor: default; +} + +.video-player.gif-mode video { + width: 100%; + max-height: 500px; + object-fit: contain; +} + [data-theme="dark"] .video-player { box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); } diff --git a/themes/Ying/layouts/shortcodes/video.html b/themes/Ying/layouts/shortcodes/video.html index 56bd7e90..e1b17b57 100644 --- a/themes/Ying/layouts/shortcodes/video.html +++ b/themes/Ying/layouts/shortcodes/video.html @@ -38,21 +38,28 @@ {{ $src := .Get "src" }} {{ $poster := .Get "poster" }} {{ $caption := .Get "caption" }} + {{ $loop := .Get "loop" | default "false" }} + {{ $muted := .Get "muted" | default "false" }} + {{ $isGifMode := or (eq $loop "true") (eq $muted "true") }} {{ $videoSrc := $src }} {{ if not (hasPrefix $src "http") }} {{ $videoSrc = printf "/%s/%s" .Page.Slug $src }} {{ end }}
-
+
+ {{ if not $isGifMode }}
@@ -73,6 +80,7 @@
+ {{ end }} {{ with $caption }}
{{ . }}
diff --git a/write-server/src/lib/bot/poll.ts b/write-server/src/lib/bot/poll.ts index a246fe56..540c979c 100644 --- a/write-server/src/lib/bot/poll.ts +++ b/write-server/src/lib/bot/poll.ts @@ -100,9 +100,10 @@ export async function startPolling(): Promise { // 处理 GIF / 文档 / 视频 if ((msg.animation || msg.document || msg.video) && hasSession(chatId)) { + const fileType = msg.animation ? "animation" : msg.video ? "video" : "document"; const file = msg.animation || msg.document || msg.video; if (file) { - await handleDocument(chatId, file.file_id, file.file_name, msg.caption); + await handleDocument(chatId, file.file_id, file.file_name, msg.caption, fileType); } continue; } @@ -228,7 +229,7 @@ async function handlePhoto(chatId: number, photos: { file_id: string }[], captio } } -async function handleDocument(chatId: number, fileId: string, fileName?: string, caption?: string) { +async function handleDocument(chatId: number, fileId: string, fileName?: string, caption?: string, fileType?: string) { try { const fs = await import("fs"); const path = await import("path"); @@ -257,14 +258,21 @@ async function handleDocument(chatId: number, fileId: string, fileName?: string, const filename = Date.now() + "-" + fileId.slice(0, 8) + "." + ext; fs.writeFileSync(path.join(articleDir, filename), Buffer.from(fileBuffer)); - // GIF 用图片语法,视频用 shortcode,其他用链接 + // 根据 Telegram 消息类型判断,而不是猜文件名 const extLower = ext.toLowerCase(); const isImage = ["gif", "webp", "png", "jpg", "jpeg"].includes(extLower); const isVideo = ["mp4", "webm", "mov", "avi", "mkv", "flv"].includes(extLower); const fileCaption = caption || fileName || "file"; + if (isImage) { appendContent(chatId, `\n![${fileCaption}](${filename})\n`); - } else if (isVideo) { + } else if (fileType === "animation") { + // Telegram GIF 动画 → 自动播放、循环、静音 + appendContent(chatId, `\n{{< video src="${filename}" loop="true" muted="true" >}}\n`); + await sendMessage(chatId, `🎞️ GIF 已保存:${filename}`); + return; + } else if (fileType === "video" || isVideo) { + // 普通视频 → 带控制栏 appendContent(chatId, `\n{{< video src="${filename}" caption="${fileCaption}" >}}\n`); await sendMessage(chatId, `🎬 视频已保存:${filename}`); return;