



























@@ -12,6 +12,7 @@ const MESSAGE_NOT_MODIFIED_RE =
1212/400:\s*Bad Request:\s*message is not modified|MESSAGE_NOT_MODIFIED/i;
1313const MESSAGE_NOT_FOUND_RE =
1414/400:\s*Bad Request:\s*message to edit not found|MESSAGE_ID_INVALID|message can't be edited/i;
15+const LONG_LIVED_PREVIEW_FRESH_FINAL_AFTER_MS = 60_000;
15161617function extractErrorText(err: unknown): string {
1718return typeof err === "string"
@@ -55,6 +56,7 @@ export type DraftLaneState = {
5556export type ArchivedPreview = {
5657messageId: number;
5758textSnapshot: string;
59+visibleSinceMs?: number;
5860// Boundary-finalized previews should remain visible even if no matching
5961// final edit arrives; superseded previews can be safely deleted.
6062deleteIfUnused?: boolean;
@@ -92,6 +94,7 @@ type CreateLaneTextDelivererParams = {
9294deletePreviewMessage: (messageId: number) => Promise<void>;
9395log: (message: string) => void;
9496markDelivered: () => void;
97+now?: () => number;
9598};
969997100type DeliverLaneTextParams = {
@@ -169,6 +172,14 @@ function shouldSkipRegressivePreviewUpdate(args: {
169172);
170173}
171174175+function isLongLivedPreview(visibleSinceMs: number | undefined, nowMs: number): boolean {
176+return (
177+typeof visibleSinceMs === "number" &&
178+Number.isFinite(visibleSinceMs) &&
179+nowMs - visibleSinceMs >= LONG_LIVED_PREVIEW_FRESH_FINAL_AFTER_MS
180+);
181+}
182+172183function resolvePreviewTarget(params: ResolvePreviewTargetParams): PreviewTargetResolution {
173184const lanePreviewMessageId = params.lane.stream?.messageId();
174185const previewMessageId =
@@ -187,11 +198,27 @@ function resolvePreviewTarget(params: ResolvePreviewTargetParams): PreviewTarget
187198188199export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
189200const getLanePreviewText = (lane: DraftLaneState) => lane.lastPartialText;
201+const readNow = () => params.now?.() ?? Date.now();
190202const markActivePreviewComplete = (laneName: LaneName) => {
191203params.activePreviewLifecycleByLane[laneName] = "complete";
192204params.retainPreviewOnCleanupByLane[laneName] = true;
193205};
194206const isDraftPreviewLane = (lane: DraftLaneState) => lane.stream?.previewMode?.() === "draft";
207+const isMessagePreviewLane = (lane: DraftLaneState) => !isDraftPreviewLane(lane);
208+const shouldUseFreshFinalForLane = (lane: DraftLaneState) =>
209+isMessagePreviewLane(lane) && isLongLivedPreview(lane.stream?.visibleSinceMs?.(), readNow());
210+const shouldUseFreshFinalForPreview = (lane: DraftLaneState, visibleSinceMs?: number) =>
211+isMessagePreviewLane(lane) && isLongLivedPreview(visibleSinceMs, readNow());
212+const clearActivePreviewAfterFreshFinal = async (lane: DraftLaneState, laneName: LaneName) => {
213+try {
214+await lane.stream?.clear();
215+} catch (err) {
216+params.log(`telegram: ${laneName} fresh final preview cleanup failed: ${String(err)}`);
217+}
218+lane.lastPartialText = "";
219+lane.hasStreamedMessage = false;
220+lane.stream?.forceNewMessage();
221+};
195222const canMaterializeDraftFinal = (
196223lane: DraftLaneState,
197224previewButtons?: TelegramInlineButtons,
@@ -444,6 +471,19 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
444471if (!archivedPreview) {
445472return undefined;
446473}
474+if (canEditViaPreview && shouldUseFreshFinalForPreview(lane, archivedPreview.visibleSinceMs)) {
475+const delivered = await params.sendPayload(params.applyTextToPayload(payload, text));
476+if (delivered) {
477+try {
478+await params.deletePreviewMessage(archivedPreview.messageId);
479+} catch (err) {
480+params.log(
481+`telegram: archived answer preview cleanup failed (${archivedPreview.messageId}): ${String(err)}`,
482+);
483+}
484+return result("sent");
485+}
486+}
447487if (canEditViaPreview) {
448488const finalized = await tryUpdatePreviewForLane({
449489 lane,
@@ -551,6 +591,14 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
551591});
552592}
553593}
594+if (shouldUseFreshFinalForLane(lane)) {
595+await params.stopDraftLane(lane);
596+const delivered = await params.sendPayload(params.applyTextToPayload(payload, text));
597+if (delivered) {
598+await clearActivePreviewAfterFreshFinal(lane, laneName);
599+return result("sent");
600+}
601+}
554602const previewMessageId = lane.stream?.messageId();
555603const finalized = await tryUpdatePreviewForLane({
556604 lane,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。