fix: handle empty media and prompt persistence

This commit is contained in:
2026-09-24 19:51:50 +08:00
parent fb354c9434
commit 6a2ba6a50a
3 changed files with 35 additions and 7 deletions
+3
View File
@@ -114,6 +114,9 @@ async fn refetch(
.iter() .iter()
.filter_map(|media| media_to_payload(media, fetched.sensitive)) .filter_map(|media| media_to_payload(media, fetched.sensitive))
.collect(); .collect();
if items.is_empty() {
return Ok(None);
}
// The re-fetch may produce a fresh local file (ugoira / bsky remux): hand it // The re-fetch may produce a fresh local file (ugoira / bsky remux): hand it
// to the same keep-alive registry the first fetch uses. // to the same keep-alive registry the first fetch uses.
if let Some(dir) = fetched.keep_alive() { if let Some(dir) = fetched.keep_alive() {
+13 -6
View File
@@ -637,10 +637,7 @@ async fn url_media_inner(
let format = chat_data.format_for(fetched.site_id); let format = chat_data.format_for(fetched.site_id);
if fetched.media.is_empty() { if fetched.media.is_empty() {
// A post with no media is still a post: its text goes out as a // A post with no media is still a post: its text goes out as a
// message (through the same caption the media path would // message through the same caption the media path would attach.
// attach, plus the long-post quoting the senders apply to
// their own), instead of answering "No media found" to text
// the fetch already parsed.
let text = fetched let text = fetched
.render_fields() .render_fields()
.map(|(_, _, title, content, _)| x_media::site::compose_text(title, content)) .map(|(_, _, title, content, _)| x_media::site::compose_text(title, content))
@@ -652,14 +649,24 @@ async fn url_media_inner(
return; return;
} }
let caption = fetched.caption_with(&format); let caption = fetched.caption_with(&format);
// Raw render data for the link cache; the send fills in the
// Telegram file ids and persists the entry.
let cache_data = cached_snapshot(fetched); let cache_data = cached_snapshot(fetched);
let items: Vec<MediaItemPayload> = fetched let items: Vec<MediaItemPayload> = fetched
.media .media
.iter() .iter()
.filter_map(|media| media_to_payload(media, fetched.sensitive)) .filter_map(|media| media_to_payload(media, fetched.sensitive))
.collect(); .collect();
if items.is_empty() {
let text = fetched
.render_fields()
.map(|(_, _, title, content, _)| x_media::site::compose_text(title, content))
.unwrap_or_default();
let caption = fetched.caption_with(&format);
let caption =
send::quote_long_caption(&caption, &text, ctx.config.caption_quote_text_chars);
send::send_text_post(ctx, chat_id, reply_to.0 as i64, caption.into_owned()).await;
return;
}
*hint.lock() = ActionHint::for_items(&items);
let task = build_send_task( let task = build_send_task(
&chat_data, &chat_data,
chat_id, chat_id,
+19 -1
View File
@@ -301,7 +301,7 @@ pub(crate) async fn post_send_actions(ctx: &AppContext<'_>, task: &Task, message
log_key(&source_url) log_key(&source_url)
); );
let source_url = source_url.clone(); let source_url = source_url.clone();
let _ = ctx let saved = match ctx
.chat_store .chat_store
.update(chat_id, move |data| { .update(chat_id, move |data| {
data.edit_message.insert( data.edit_message.insert(
@@ -315,7 +315,25 @@ pub(crate) async fn post_send_actions(ctx: &AppContext<'_>, task: &Task, message
}, },
); );
}) })
.await
{
Ok((_, true)) => true,
Ok((_, false)) | Err(()) => false,
};
if !saved {
log::error!("edit prompt {prompt_id} could not be persisted; removing it");
let _ = ctx
.sender
.delete_message(ChatId(chat_id), MessageId(prompt_id as i32))
.await;
notify_failure(
ctx.sender,
notify_chat_id,
notify_message_id,
"Could not save the edit-before-forward prompt — nothing was forwarded.",
)
.await; .await;
}
} }
Err(e) => { Err(e) => {
log::error!("failed to send edit prompt: {e}"); log::error!("failed to send edit prompt: {e}");