

























@@ -53,8 +53,38 @@ type SupersededTelegramPreview = {
5353textSnapshot: string;
5454parseMode?: "HTML";
5555visibleSinceMs?: number;
56+retain?: boolean;
5657};
575859+function renderTelegramDraftPreview(
60+text: string,
61+renderText: ((text: string) => TelegramDraftPreview) | undefined,
62+): TelegramDraftPreview {
63+const trimmed = text.trimEnd();
64+return renderText?.(trimmed) ?? { text: trimmed };
65+}
66+67+function findTelegramDraftChunkLength(
68+text: string,
69+maxChars: number,
70+renderText: ((text: string) => TelegramDraftPreview) | undefined,
71+): number {
72+let best = 0;
73+let low = 1;
74+let high = text.length;
75+while (low <= high) {
76+const mid = Math.floor((low + high) / 2);
77+const renderedText = renderTelegramDraftPreview(text.slice(0, mid), renderText).text.trimEnd();
78+if (renderedText && renderedText.length <= maxChars) {
79+best = mid;
80+low = mid + 1;
81+} else {
82+high = mid - 1;
83+}
84+}
85+return best;
86+}
87+5888export function createTelegramDraftStream(params: {
5989api: Bot["api"];
6090chatId: Parameters<Bot["api"]["sendMessage"]>[0];
@@ -98,6 +128,8 @@ export function createTelegramDraftStream(params: {
98128let lastSentParseMode: "HTML" | undefined;
99129let previewRevision = 0;
100130let generation = 0;
131+let deliveredTextOffset = 0;
132+let resetStreamToNewMessage: (options?: { keepPending?: boolean; resetOffset?: boolean }) => void;
101133type PreviewSendParams = {
102134renderedText: string;
103135renderedParseMode: "HTML" | undefined;
@@ -198,13 +230,45 @@ export function createTelegramDraftStream(params: {
198230if (!trimmed) {
199231return false;
200232}
201-const rendered = params.renderText?.(trimmed) ?? { text: trimmed };
233+const currentText = trimmed.slice(deliveredTextOffset).trimStart();
234+if (!currentText) {
235+return false;
236+}
237+const rendered = renderTelegramDraftPreview(currentText, params.renderText);
202238const renderedText = rendered.text.trimEnd();
203239const renderedParseMode = rendered.parseMode;
204240if (!renderedText) {
205241return false;
206242}
207243if (renderedText.length > maxChars) {
244+if (lastDeliveredText.length > deliveredTextOffset) {
245+const supersededMessageId = streamMessageId;
246+const supersededTextSnapshot = lastSentText;
247+const supersededParseMode = lastSentParseMode;
248+const supersededVisibleSinceMs = streamVisibleSinceMs;
249+deliveredTextOffset = lastDeliveredText.length;
250+resetStreamToNewMessage({ keepPending: true, resetOffset: false });
251+if (typeof supersededMessageId === "number") {
252+params.onSupersededPreview?.({
253+messageId: supersededMessageId,
254+textSnapshot: supersededTextSnapshot,
255+parseMode: supersededParseMode,
256+visibleSinceMs: supersededVisibleSinceMs,
257+retain: true,
258+});
259+}
260+return await sendOrEditStreamMessage(trimmed);
261+}
262+const chunkLength = findTelegramDraftChunkLength(currentText, maxChars, params.renderText);
263+if (chunkLength > 0) {
264+const sent = await sendOrEditStreamMessage(
265+trimmed.slice(0, deliveredTextOffset) + currentText.slice(0, chunkLength),
266+);
267+if (!sent) {
268+return false;
269+}
270+return await sendOrEditStreamMessage(trimmed);
271+}
208272streamState.stopped = true;
209273params.warn?.(
210274`telegram stream preview stopped (text length ${renderedText.length} > ${maxChars})`,
@@ -248,6 +312,24 @@ export function createTelegramDraftStream(params: {
248312 sendOrEditStreamMessage,
249313});
250314315+resetStreamToNewMessage = (options) => {
316+streamState.stopped = false;
317+streamState.final = false;
318+generation += 1;
319+messageSendAttempted = false;
320+streamMessageId = undefined;
321+streamVisibleSinceMs = undefined;
322+lastSentText = "";
323+lastSentParseMode = undefined;
324+if (options?.resetOffset !== false) {
325+deliveredTextOffset = 0;
326+}
327+if (!options?.keepPending) {
328+loop.resetPending();
329+}
330+loop.resetThrottleWindow();
331+};
332+251333const clear = async () => {
252334const messageId = await takeMessageIdAfterStop({
253335 stopForClear,
@@ -272,16 +354,7 @@ export function createTelegramDraftStream(params: {
272354};
273355274356const forceNewMessage = () => {
275-streamState.stopped = false;
276-streamState.final = false;
277-generation += 1;
278-messageSendAttempted = false;
279-streamMessageId = undefined;
280-streamVisibleSinceMs = undefined;
281-lastSentText = "";
282-lastSentParseMode = undefined;
283-loop.resetPending();
284-loop.resetThrottleWindow();
357+resetStreamToNewMessage();
285358};
286359287360const materialize = async (): Promise<number | undefined> => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。