Message: Stop media download on deletion (#4978)
This commit is contained in:
parent
f5675ca3fc
commit
73d9fe9756
@ -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') {
|
||||
|
||||
@ -248,7 +248,7 @@ const Audio: FC<OwnProps> = ({
|
||||
if (isDownloading) {
|
||||
cancelMediaDownload({ media });
|
||||
} else {
|
||||
downloadMedia({ media });
|
||||
downloadMedia({ media, originMessage: message });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -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(() => {
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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 });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -505,7 +505,7 @@ const ContextMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
if (isDownloading) {
|
||||
cancelMediaDownload({ media: downloadableMedia });
|
||||
} else {
|
||||
downloadMedia({ media: downloadableMedia });
|
||||
downloadMedia({ media: downloadableMedia, originMessage: msg });
|
||||
}
|
||||
});
|
||||
closeMenu();
|
||||
|
||||
@ -1186,6 +1186,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
{document && (
|
||||
<Document
|
||||
document={document}
|
||||
message={message}
|
||||
observeIntersection={observeIntersectionForLoading}
|
||||
canAutoLoad={canAutoLoadMedia}
|
||||
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}
|
||||
|
||||
@ -252,6 +252,7 @@ const WebPage: FC<OwnProps> = ({
|
||||
{!inPreview && document && (
|
||||
<Document
|
||||
document={document}
|
||||
message={message}
|
||||
observeIntersection={observeIntersectionForLoading}
|
||||
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}
|
||||
onMediaClick={handleMediaClick}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -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);
|
||||
});
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user