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 { MethodArgs, MethodResponse, Methods } from '../methods/types';
|
||||||
import type { OriginPayload, ThenArg, WorkerMessageEvent } from './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 { logDebugMessage } from '../../../util/debugConsole';
|
||||||
import Deferred from '../../../util/Deferred';
|
import Deferred from '../../../util/Deferred';
|
||||||
import { getCurrentTabId, subscribeToMasterChange } from '../../../util/establishMultitabRole';
|
import { getCurrentTabId, subscribeToMasterChange } from '../../../util/establishMultitabRole';
|
||||||
@ -295,7 +295,9 @@ function subscribeToWorker(onUpdate: OnApiUpdate) {
|
|||||||
} else if (payload.type === 'methodCallback') {
|
} else if (payload.type === 'methodCallback') {
|
||||||
handleMethodCallback(payload);
|
handleMethodCallback(payload);
|
||||||
} else if (payload.type === 'unhandledError') {
|
} 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') {
|
} else if (payload.type === 'sendBeacon') {
|
||||||
navigator.sendBeacon(payload.url, payload.data);
|
navigator.sendBeacon(payload.url, payload.data);
|
||||||
} else if (payload.type === 'debugLog') {
|
} else if (payload.type === 'debugLog') {
|
||||||
|
|||||||
@ -248,7 +248,7 @@ const Audio: FC<OwnProps> = ({
|
|||||||
if (isDownloading) {
|
if (isDownloading) {
|
||||||
cancelMediaDownload({ media });
|
cancelMediaDownload({ media });
|
||||||
} else {
|
} else {
|
||||||
downloadMedia({ media });
|
downloadMedia({ media, originMessage: message });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,7 @@ type OwnProps = {
|
|||||||
message: ApiMessage;
|
message: ApiMessage;
|
||||||
onDateClick: (arg: ApiMessage) => void;
|
onDateClick: (arg: ApiMessage) => void;
|
||||||
} | {
|
} | {
|
||||||
message?: never;
|
message?: ApiMessage;
|
||||||
onDateClick?: never;
|
onDateClick?: never;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ const Document = ({
|
|||||||
const withMediaViewer = onMediaClick && document.innerMediaType;
|
const withMediaViewer = onMediaClick && document.innerMediaType;
|
||||||
|
|
||||||
const handleDownload = useLastCallback(() => {
|
const handleDownload = useLastCallback(() => {
|
||||||
downloadMedia({ media: document });
|
downloadMedia({ media: document, originMessage: message });
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleClick = useLastCallback(() => {
|
const handleClick = useLastCallback(() => {
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
import type { FC } from '../../lib/teact/teact';
|
import type { FC } from '../../lib/teact/teact';
|
||||||
import { memo, useEffect } 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 type { TabState } from '../../global/types';
|
||||||
import { ApiMediaFormat } from '../../api/types';
|
import { ApiMediaFormat } from '../../api/types';
|
||||||
|
|
||||||
import { selectTabState } from '../../global/selectors';
|
import { selectTabState } from '../../global/selectors';
|
||||||
import download from '../../util/download';
|
import download from '../../util/download';
|
||||||
|
import generateUniqueId from '../../util/generateUniqueId';
|
||||||
import * as mediaLoader from '../../util/mediaLoader';
|
import * as mediaLoader from '../../util/mediaLoader';
|
||||||
import { IS_OPFS_SUPPORTED, IS_SERVICE_WORKER_SUPPORTED, MAX_BUFFER_SIZE } from '../../util/windowEnvironment';
|
import { IS_OPFS_SUPPORTED, IS_SERVICE_WORKER_SUPPORTED, MAX_BUFFER_SIZE } from '../../util/windowEnvironment';
|
||||||
|
|
||||||
@ -69,7 +70,14 @@ const DownloadManager: FC<StateProps> = ({
|
|||||||
return;
|
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) {
|
if (mediaFormat === ApiMediaFormat.DownloadUrl) {
|
||||||
const url = new URL(result, window.document.baseURI);
|
const url = new URL(result, window.document.baseURI);
|
||||||
url.searchParams.set('filename', encodeURIComponent(filename));
|
url.searchParams.set('filename', encodeURIComponent(filename));
|
||||||
|
|||||||
@ -110,7 +110,8 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
|
|||||||
if (isDownloading) {
|
if (isDownloading) {
|
||||||
cancelMediaDownload({ media });
|
cancelMediaDownload({ media });
|
||||||
} else {
|
} 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) {
|
if (isDownloading) {
|
||||||
cancelMediaDownload({ media: downloadableMedia });
|
cancelMediaDownload({ media: downloadableMedia });
|
||||||
} else {
|
} else {
|
||||||
downloadMedia({ media: downloadableMedia });
|
downloadMedia({ media: downloadableMedia, originMessage: msg });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
closeMenu();
|
closeMenu();
|
||||||
|
|||||||
@ -1186,6 +1186,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
{document && (
|
{document && (
|
||||||
<Document
|
<Document
|
||||||
document={document}
|
document={document}
|
||||||
|
message={message}
|
||||||
observeIntersection={observeIntersectionForLoading}
|
observeIntersection={observeIntersectionForLoading}
|
||||||
canAutoLoad={canAutoLoadMedia}
|
canAutoLoad={canAutoLoadMedia}
|
||||||
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}
|
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}
|
||||||
|
|||||||
@ -252,6 +252,7 @@ const WebPage: FC<OwnProps> = ({
|
|||||||
{!inPreview && document && (
|
{!inPreview && document && (
|
||||||
<Document
|
<Document
|
||||||
document={document}
|
document={document}
|
||||||
|
message={message}
|
||||||
observeIntersection={observeIntersectionForLoading}
|
observeIntersection={observeIntersectionForLoading}
|
||||||
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}
|
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}
|
||||||
onMediaClick={handleMediaClick}
|
onMediaClick={handleMediaClick}
|
||||||
|
|||||||
@ -342,6 +342,10 @@ export const PEER_COLOR_GRADIENT_STEP = 5; // px
|
|||||||
export const MAX_UPLOAD_FILEPART_SIZE = 524288;
|
export const MAX_UPLOAD_FILEPART_SIZE = 524288;
|
||||||
export const MAX_UNIQUE_REACTIONS = 11;
|
export const MAX_UNIQUE_REACTIONS = 11;
|
||||||
|
|
||||||
|
export const IGNORE_UNHANDLED_ERRORS = new Set([
|
||||||
|
'USER_CANCELED',
|
||||||
|
]);
|
||||||
|
|
||||||
// Group calls
|
// Group calls
|
||||||
export const GROUP_CALL_VOLUME_MULTIPLIER = 100;
|
export const GROUP_CALL_VOLUME_MULTIPLIER = 100;
|
||||||
export const GROUP_CALL_DEFAULT_VOLUME = 100 * GROUP_CALL_VOLUME_MULTIPLIER;
|
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 => {
|
addActionHandler('downloadMedia', (global, actions, payload): ActionReturnType => {
|
||||||
const { media, tabId = getCurrentTabId() } = payload;
|
const { media, originMessage, tabId = getCurrentTabId() } = payload;
|
||||||
|
|
||||||
const hash = getMediaHash(media, 'download');
|
const hash = getMediaHash(media, 'download');
|
||||||
if (!hash) return undefined;
|
if (!hash) return undefined;
|
||||||
@ -637,6 +637,8 @@ addActionHandler('downloadMedia', (global, actions, payload): ActionReturnType =
|
|||||||
size,
|
size,
|
||||||
format: getMediaFormat(media, 'download'),
|
format: getMediaFormat(media, 'download'),
|
||||||
filename: getMediaFilename(media),
|
filename: getMediaFilename(media),
|
||||||
|
originChatId: originMessage?.chatId,
|
||||||
|
originMessageId: originMessage?.id,
|
||||||
} satisfies ActiveDownloads[string];
|
} satisfies ActiveDownloads[string];
|
||||||
|
|
||||||
return addActiveMediaDownload(global, hash, metadata, tabId);
|
return addActiveMediaDownload(global, hash, metadata, tabId);
|
||||||
@ -659,7 +661,7 @@ addActionHandler('downloadSelectedMessages', (global, actions, payload): ActionR
|
|||||||
messages.forEach((message) => {
|
messages.forEach((message) => {
|
||||||
const media = getMessageDownloadableMedia(message);
|
const media = getMessageDownloadableMedia(message);
|
||||||
if (!media) return;
|
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 }) => {
|
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) => {
|
mediaIdsToRemove.forEach((mediaId) => {
|
||||||
global = removeIdFromSearchResults(global, chatId, threadId, mediaId, tabId);
|
global = removeIdFromSearchResults(global, chatId, threadId, mediaId, tabId);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -162,6 +162,8 @@ export type ActiveDownloads = Record<string, {
|
|||||||
format: ApiMediaFormat;
|
format: ApiMediaFormat;
|
||||||
filename: string;
|
filename: string;
|
||||||
size: number;
|
size: number;
|
||||||
|
originChatId?: string;
|
||||||
|
originMessageId?: number;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type IDimensions = {
|
export type IDimensions = {
|
||||||
@ -2632,6 +2634,7 @@ export interface ActionPayloads {
|
|||||||
downloadSelectedMessages: WithTabId | undefined;
|
downloadSelectedMessages: WithTabId | undefined;
|
||||||
downloadMedia: {
|
downloadMedia: {
|
||||||
media: DownloadableMedia;
|
media: DownloadableMedia;
|
||||||
|
originMessage?: ApiMessage;
|
||||||
} & WithTabId;
|
} & WithTabId;
|
||||||
cancelMediaDownload: {
|
cancelMediaDownload: {
|
||||||
media: DownloadableMedia;
|
media: DownloadableMedia;
|
||||||
|
|||||||
@ -50,6 +50,7 @@ function handleErrorEvent(e: ErrorEvent | PromiseRejectionEvent) {
|
|||||||
if (e instanceof ErrorEvent && e.message === 'ResizeObserver loop limit exceeded') {
|
if (e instanceof ErrorEvent && e.message === 'ResizeObserver loop limit exceeded') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
handleError(e instanceof ErrorEvent ? (e.error || e.message) : e.reason);
|
handleError(e instanceof ErrorEvent ? (e.error || e.message) : e.reason);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user