mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-06-03 14:39:56 +08:00
fix: delay transient typing indicators
This commit is contained in:
@@ -82,6 +82,7 @@ class Discord:
|
||||
self._typing_tasks: Dict[str, asyncio.Task] = {}
|
||||
self._typing_stop_events: Dict[str, asyncio.Event] = {}
|
||||
self._typing_interval_seconds = 5
|
||||
self._typing_initial_delay_seconds = 1
|
||||
self._typing_max_duration_seconds = 5 * 60
|
||||
|
||||
self._register_events()
|
||||
@@ -379,6 +380,7 @@ class Discord:
|
||||
userid: Optional[str] = None,
|
||||
chat_id: Optional[str] = None,
|
||||
max_duration_seconds: Optional[float] = None,
|
||||
initial_delay_seconds: Optional[float] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
持续发送 Discord typing 指示,直到显式停止或达到最大续期。
|
||||
@@ -395,6 +397,7 @@ class Discord:
|
||||
userid=userid,
|
||||
chat_id=chat_id,
|
||||
max_duration_seconds=max_duration_seconds,
|
||||
initial_delay_seconds=initial_delay_seconds,
|
||||
),
|
||||
self._loop,
|
||||
)
|
||||
@@ -438,6 +441,7 @@ class Discord:
|
||||
userid: Optional[str] = None,
|
||||
chat_id: Optional[str] = None,
|
||||
max_duration_seconds: Optional[float] = None,
|
||||
initial_delay_seconds: Optional[float] = None,
|
||||
) -> bool:
|
||||
await self._stop_typing_task(typing_key)
|
||||
channel = await self._resolve_channel(userid=userid, chat_id=chat_id)
|
||||
@@ -445,10 +449,26 @@ class Discord:
|
||||
return False
|
||||
stop_event = asyncio.Event()
|
||||
max_duration = max_duration_seconds or self._typing_max_duration_seconds
|
||||
initial_delay = (
|
||||
self._typing_initial_delay_seconds
|
||||
if initial_delay_seconds is None
|
||||
else max(initial_delay_seconds, 0)
|
||||
)
|
||||
|
||||
async def _typing_worker() -> None:
|
||||
started_at = self._loop.time()
|
||||
try:
|
||||
# Discord typing 触发后也会在客户端自然保留一段时间,
|
||||
# 先给短响应一个取消窗口,避免回复后残留输入状态。
|
||||
if initial_delay:
|
||||
try:
|
||||
await asyncio.wait_for(
|
||||
stop_event.wait(),
|
||||
timeout=initial_delay,
|
||||
)
|
||||
return
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
while not stop_event.is_set():
|
||||
if self._loop.time() - started_at >= max_duration:
|
||||
logger.warning(
|
||||
|
||||
@@ -46,6 +46,7 @@ class Telegram:
|
||||
_typing_stop_flags: Dict[str, threading.Event] = {} # chat_id -> 停止信号
|
||||
_typing_lock = threading.RLock()
|
||||
_typing_interval_seconds = 5
|
||||
_typing_initial_delay_seconds = 1
|
||||
_typing_max_duration_seconds = 5 * 60
|
||||
_typing_command_max_duration_seconds = 30
|
||||
_typing_callback_max_duration_seconds = 60
|
||||
@@ -340,6 +341,7 @@ class Telegram:
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
max_duration_seconds: Optional[float] = None,
|
||||
initial_delay_seconds: Optional[float] = None,
|
||||
) -> None:
|
||||
"""
|
||||
启动持续发送正在输入状态的任务
|
||||
@@ -351,11 +353,20 @@ class Telegram:
|
||||
# 使用独立 Event 避免同一 chat 新旧 typing 线程互相误改停止标记。
|
||||
stop_event = threading.Event()
|
||||
max_duration = max_duration_seconds or self._typing_max_duration_seconds
|
||||
initial_delay = (
|
||||
self._typing_initial_delay_seconds
|
||||
if initial_delay_seconds is None
|
||||
else max(initial_delay_seconds, 0)
|
||||
)
|
||||
|
||||
def typing_worker():
|
||||
"""定期发送typing状态的后台线程"""
|
||||
"""延迟首发并定期发送 typing 状态的后台线程。"""
|
||||
started_at = time.monotonic()
|
||||
try:
|
||||
# Telegram 没有撤销 typing 的接口,短响应先等待一小段时间,
|
||||
# 避免回复已经发出后客户端仍残留几秒“正在输入”。
|
||||
if initial_delay and stop_event.wait(initial_delay):
|
||||
return
|
||||
while not stop_event.is_set():
|
||||
if time.monotonic() - started_at >= max_duration:
|
||||
logger.warning(
|
||||
|
||||
Reference in New Issue
Block a user