Message: Stop media download on deletion (#4978)

This commit is contained in:
zubiden 2024-09-19 20:43:55 +02:00 committed by Alexander Zinchuk
parent f5675ca3fc
commit 73d9fe9756
13 changed files with 45 additions and 11 deletions

View File

@ -5,7 +5,7 @@ import type { LocalDb } from '../localDb';
import type { MethodArgs, MethodResponse, Methods } from '../methods/types';
import type { OriginPayload, ThenArg, WorkerMessageEvent } from './types';
import { DATA_BROADCAST_CHANNEL_NAME, DEBUG } from '../../../config';
import { DATA_BROADCAST_CHANNEL_NAME, DEBUG, IGNORE_UNHANDLED_ERRORS } from '../../../config';
import { logDebugMessage } from '../../../util/debugConsole';
import Deferred from '../../../util/Deferred';
import { getCurrentTabId, subscribeToMasterChange } from '../../../util/establishMultitabRole';
@ -295,7 +295,9 @@ function subscribeToWorker(onUpdate: OnApiUpdate) {
} else if (payload.type === 'methodCallback') {
handleMethodCallback(payload);
} else if (payload.type === 'unhandledError') {
throw new Error(payload.error?.message);
const message = payload.error?.message;
if (message && IGNORE_UNHANDLED_ERRORS.has(message)) return;
throw new Error(message);
} else if (payload.type === 'sendBeacon') {
navigator.sendBeacon(payload.url, payload.data);
} else if (payload.type === 'debugLog') {

View File

@ -248,7 +248,7 @@ const Audio: FC<OwnProps> = ({
if (isDownloading) {
cancelMediaDownload({ media });
} else {
downloadMedia({ media });
downloadMedia({ media, originMessage: message });
}
});

View File

@ -47,7 +47,7 @@ type OwnProps = {
message: ApiMessage;
onDateClick: (arg: ApiMessage) => void;
} | {
message?: never;
message?: ApiMessage;
onDateClick?: never;
});
@ -123,7 +123,7 @@ const Document = ({
const withMediaViewer = onMediaClick && document.innerMediaType;
const handleDownload = useLastCallback(() => {
downloadMedia({ media: document });
downloadMedia({ media: document, originMessage: message });
});
const handleClick = useLastCallback(() => {

View File

@ -1,12 +1,13 @@
import type { FC } from '../../lib/teact/teact';
import { memo, useEffect } from '../../lib/teact/teact';
import { getActions, withGlobal } from '../../global';
import { getActions, getGlobal, withGlobal } from '../../global';
import type { TabState } from '../../global/types';
import { ApiMediaFormat } from '../../api/types';
import { selectTabState } from '../../global/selectors';
import download from '../../util/download';
import generateUniqueId from '../../util/generateUniqueId';
import * as mediaLoader from '../../util/mediaLoader';
import { IS_OPFS_SUPPORTED, IS_SERVICE_WORKER_SUPPORTED, MAX_BUFFER_SIZE } from '../../util/windowEnvironment';
@ -69,7 +70,14 @@ const DownloadManager: FC<StateProps> = ({
return;
}
mediaLoader.fetch(mediaHash, mediaFormat, true).then((result) => {
const handleProgress = () => {
const currentDownloads = selectTabState(getGlobal()).activeDownloads;
if (!currentDownloads[mediaHash]) {
mediaLoader.cancelProgress(handleProgress);
}
};
mediaLoader.fetch(mediaHash, mediaFormat, true, handleProgress, generateUniqueId()).then((result) => {
if (mediaFormat === ApiMediaFormat.DownloadUrl) {
const url = new URL(result, window.document.baseURI);
url.searchParams.set('filename', encodeURIComponent(filename));

View File

@ -110,7 +110,8 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
if (isDownloading) {
cancelMediaDownload({ media });
} else {
downloadMedia({ media });
const message = item?.type === 'message' ? item.message : undefined;
downloadMedia({ media, originMessage: message });
}
});

View File

@ -505,7 +505,7 @@ const ContextMenuContainer: FC<OwnProps & StateProps> = ({
if (isDownloading) {
cancelMediaDownload({ media: downloadableMedia });
} else {
downloadMedia({ media: downloadableMedia });
downloadMedia({ media: downloadableMedia, originMessage: msg });
}
});
closeMenu();

View File

@ -1186,6 +1186,7 @@ const Message: FC<OwnProps & StateProps> = ({
{document && (
<Document
document={document}
message={message}
observeIntersection={observeIntersectionForLoading}
canAutoLoad={canAutoLoadMedia}
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}

View File

@ -252,6 +252,7 @@ const WebPage: FC<OwnProps> = ({
{!inPreview && document && (
<Document
document={document}
message={message}
observeIntersection={observeIntersectionForLoading}
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}
onMediaClick={handleMediaClick}

View File

@ -342,6 +342,10 @@ export const PEER_COLOR_GRADIENT_STEP = 5; // px
export const MAX_UPLOAD_FILEPART_SIZE = 524288;
export const MAX_UNIQUE_REACTIONS = 11;
export const IGNORE_UNHANDLED_ERRORS = new Set([
'USER_CANCELED',
]);
// Group calls
export const GROUP_CALL_VOLUME_MULTIPLIER = 100;
export const GROUP_CALL_DEFAULT_VOLUME = 100 * GROUP_CALL_VOLUME_MULTIPLIER;

View File

@ -627,7 +627,7 @@ addActionHandler('cancelMediaHashDownloads', (global, actions, payload): ActionR
});
addActionHandler('downloadMedia', (global, actions, payload): ActionReturnType => {
const { media, tabId = getCurrentTabId() } = payload;
const { media, originMessage, tabId = getCurrentTabId() } = payload;
const hash = getMediaHash(media, 'download');
if (!hash) return undefined;
@ -637,6 +637,8 @@ addActionHandler('downloadMedia', (global, actions, payload): ActionReturnType =
size,
format: getMediaFormat(media, 'download'),
filename: getMediaFilename(media),
originChatId: originMessage?.chatId,
originMessageId: originMessage?.id,
} satisfies ActiveDownloads[string];
return addActiveMediaDownload(global, hash, metadata, tabId);
@ -659,7 +661,7 @@ addActionHandler('downloadSelectedMessages', (global, actions, payload): ActionR
messages.forEach((message) => {
const media = getMessageDownloadableMedia(message);
if (!media) return;
actions.downloadMedia({ media, tabId });
actions.downloadMedia({ media, originMessage: message, tabId });
});
});

View File

@ -354,6 +354,17 @@ export function deleteChatMessages<T extends GlobalState>(
}
Object.values(global.byTabId).forEach(({ id: tabId }) => {
const tabState = selectTabState(global, tabId);
const activeDownloadsInChat = Object.entries(tabState.activeDownloads).filter(
([, { originChatId, originMessageId }]) => originChatId === chatId && originMessageId,
);
activeDownloadsInChat.forEach(([mediaHash, context]) => {
if (messageIds.includes(context.originMessageId!)) {
global = cancelMessageMediaDownload(global, [mediaHash], tabId);
}
});
mediaIdsToRemove.forEach((mediaId) => {
global = removeIdFromSearchResults(global, chatId, threadId, mediaId, tabId);
});

View File

@ -162,6 +162,8 @@ export type ActiveDownloads = Record<string, {
format: ApiMediaFormat;
filename: string;
size: number;
originChatId?: string;
originMessageId?: number;
}>;
export type IDimensions = {
@ -2632,6 +2634,7 @@ export interface ActionPayloads {
downloadSelectedMessages: WithTabId | undefined;
downloadMedia: {
media: DownloadableMedia;
originMessage?: ApiMessage;
} & WithTabId;
cancelMediaDownload: {
media: DownloadableMedia;

View File

@ -50,6 +50,7 @@ function handleErrorEvent(e: ErrorEvent | PromiseRejectionEvent) {
if (e instanceof ErrorEvent && e.message === 'ResizeObserver loop limit exceeded') {
return;
}
e.preventDefault();
handleError(e instanceof ErrorEvent ? (e.error || e.message) : e.reason);
}