Media Message: Fix playing voice and audio after send (#4347)
This commit is contained in:
parent
c23752a28e
commit
b8b8c15919
@ -129,6 +129,9 @@ const AudioPlayer: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleClose = useLastCallback(() => {
|
||||
if (!stop) {
|
||||
return;
|
||||
}
|
||||
if (isPlaying) {
|
||||
playPause();
|
||||
}
|
||||
@ -138,18 +141,26 @@ const AudioPlayer: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleVolumeChange = useLastCallback((value: number) => {
|
||||
if (!setVolume) {
|
||||
return;
|
||||
}
|
||||
setAudioPlayerVolume({ volume: value / 100 });
|
||||
|
||||
setVolume(value / 100);
|
||||
});
|
||||
|
||||
const handleVolumeClick = useLastCallback(() => {
|
||||
if (IS_TOUCH_ENV && !IS_IOS) return;
|
||||
if (!toggleMuted) {
|
||||
return;
|
||||
}
|
||||
toggleMuted();
|
||||
setAudioPlayerMuted({ isMuted: !isMuted });
|
||||
});
|
||||
|
||||
const updatePlaybackRate = useLastCallback((newRate: number, isActive = true) => {
|
||||
if (!setPlaybackRate) {
|
||||
return;
|
||||
}
|
||||
const rate = PLAYBACK_RATES[newRate];
|
||||
const shouldBeActive = newRate !== REGULAR_PLAYBACK_RATE && isActive;
|
||||
setAudioPlayerPlaybackRate({ playbackRate: rate, isPlaybackRateActive: shouldBeActive });
|
||||
@ -227,7 +238,7 @@ const AudioPlayer: FC<OwnProps & StateProps> = ({
|
||||
color="translucent"
|
||||
size="smaller"
|
||||
className="player-button"
|
||||
disabled={isFirst()}
|
||||
disabled={isFirst?.()}
|
||||
onClick={requestPreviousTrack}
|
||||
ariaLabel="Previous track"
|
||||
>
|
||||
@ -251,7 +262,7 @@ const AudioPlayer: FC<OwnProps & StateProps> = ({
|
||||
color="translucent"
|
||||
size="smaller"
|
||||
className="player-button"
|
||||
disabled={isLast()}
|
||||
disabled={isLast?.()}
|
||||
onClick={requestNextTrack}
|
||||
ariaLabel="Next track"
|
||||
>
|
||||
|
||||
@ -31,7 +31,6 @@ import {
|
||||
isChatChannel,
|
||||
isChatGroup,
|
||||
isChatWithRepliesBot,
|
||||
isLocalMessageId,
|
||||
isUserId,
|
||||
} from '../../global/helpers';
|
||||
import {
|
||||
@ -57,6 +56,7 @@ import {
|
||||
import animateScroll, { isAnimatingScroll, restartCurrentScrollAnimation } from '../../util/animateScroll';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
import { orderBy } from '../../util/iteratees';
|
||||
import { isLocalMessageId } from '../../util/messageKey';
|
||||
import resetScroll from '../../util/resetScroll';
|
||||
import { debounce, onTickEnd } from '../../util/schedulers';
|
||||
import { groupMessages } from './helpers/groupMessages';
|
||||
|
||||
@ -36,6 +36,7 @@ import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { getOrderedIds } from '../../../util/folderManager';
|
||||
import { buildCollectionByKey, omit, pick } from '../../../util/iteratees';
|
||||
import * as langProvider from '../../../util/langProvider';
|
||||
import { isLocalMessageId } from '../../../util/messageKey';
|
||||
import { debounce, pause, throttle } from '../../../util/schedulers';
|
||||
import { extractCurrentThemeParams } from '../../../util/themeStyle';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
@ -45,7 +46,6 @@ import {
|
||||
isChatBasicGroup,
|
||||
isChatChannel,
|
||||
isChatSuperGroup,
|
||||
isLocalMessageId,
|
||||
isUserBot,
|
||||
toChannelId,
|
||||
} from '../../helpers';
|
||||
|
||||
@ -45,7 +45,7 @@ import {
|
||||
unique,
|
||||
} from '../../../util/iteratees';
|
||||
import { translate } from '../../../util/langProvider';
|
||||
import { getMessageKey } from '../../../util/messageKey';
|
||||
import { getMessageKey, isLocalMessageId } from '../../../util/messageKey';
|
||||
import { debounce, onTickEnd, rafPromise } from '../../../util/schedulers';
|
||||
import { IS_IOS } from '../../../util/windowEnvironment';
|
||||
import { callApi, cancelApiProgress } from '../../../api/gramjs';
|
||||
@ -54,7 +54,6 @@ import {
|
||||
getUserFullName,
|
||||
isChatChannel,
|
||||
isDeletedUser,
|
||||
isLocalMessageId,
|
||||
isMessageLocal,
|
||||
isServiceNotificationMessage,
|
||||
isUserBot,
|
||||
|
||||
@ -4,9 +4,10 @@ import { MAIN_THREAD_ID } from '../../../api/types';
|
||||
|
||||
import { ARCHIVED_FOLDER_ID, MAX_ACTIVE_PINNED_CHATS } from '../../../config';
|
||||
import { buildCollectionByKey, omit } from '../../../util/iteratees';
|
||||
import { isLocalMessageId } from '../../../util/messageKey';
|
||||
import { closeMessageNotifications, notifyAboutMessage } from '../../../util/notifications';
|
||||
import { buildLocalMessage } from '../../../api/gramjs/apiBuilders/messages';
|
||||
import { isChatChannel, isLocalMessageId } from '../../helpers';
|
||||
import { isChatChannel } from '../../helpers';
|
||||
import {
|
||||
addActionHandler, getGlobal, setGlobal,
|
||||
} from '../../index';
|
||||
|
||||
@ -12,11 +12,11 @@ import { SERVICE_NOTIFICATIONS_USER_ID } from '../../../config';
|
||||
import { areDeepEqual } from '../../../util/areDeepEqual';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { omit, pickTruthy, unique } from '../../../util/iteratees';
|
||||
import { getMessageKey } from '../../../util/messageKey';
|
||||
import { getMessageKey, isLocalMessageId } from '../../../util/messageKey';
|
||||
import { notifyAboutMessage } from '../../../util/notifications';
|
||||
import { onTickEnd } from '../../../util/schedulers';
|
||||
import {
|
||||
checkIfHasUnreadReactions, getIsSavedDialog, getMessageContent, getMessageText, isActionMessage, isLocalMessageId,
|
||||
checkIfHasUnreadReactions, getIsSavedDialog, getMessageContent, getMessageText, isActionMessage,
|
||||
isMessageLocal, isUserId,
|
||||
} from '../../helpers';
|
||||
import { getMessageReplyInfo, getStoryReplyInfo } from '../../helpers/replies';
|
||||
|
||||
@ -498,26 +498,30 @@ function omitLocalMedia(message: ApiMessage): ApiMessage {
|
||||
photo, video, document, sticker,
|
||||
} = message.content;
|
||||
|
||||
if (photo) {
|
||||
photo.blobUrl = undefined;
|
||||
}
|
||||
|
||||
if (video) {
|
||||
video.blobUrl = undefined;
|
||||
video.previewBlobUrl = undefined;
|
||||
}
|
||||
|
||||
if (document) {
|
||||
document.previewBlobUrl = undefined;
|
||||
}
|
||||
|
||||
if (sticker) {
|
||||
sticker.isPreloadedGlobally = undefined;
|
||||
}
|
||||
|
||||
message.previousLocalId = undefined;
|
||||
|
||||
return message;
|
||||
return {
|
||||
...message,
|
||||
content: {
|
||||
...message.content,
|
||||
photo: photo && {
|
||||
...photo,
|
||||
blobUrl: undefined,
|
||||
},
|
||||
video: video && {
|
||||
...video,
|
||||
blobUrl: undefined,
|
||||
previewBlobUrl: undefined,
|
||||
},
|
||||
document: document && {
|
||||
...document,
|
||||
previewBlobUrl: undefined,
|
||||
},
|
||||
sticker: sticker && {
|
||||
...sticker,
|
||||
isPreloadedGlobally: undefined,
|
||||
},
|
||||
},
|
||||
previousLocalId: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function reduceSettings<T extends GlobalState>(global: T): GlobalState['settings'] {
|
||||
|
||||
@ -14,7 +14,7 @@ import type {
|
||||
} from '../../api/types';
|
||||
import { ApiMediaFormat } from '../../api/types';
|
||||
|
||||
import { getMessageKey } from '../../util/messageKey';
|
||||
import { getMessageServerKey } from '../../util/messageKey';
|
||||
import {
|
||||
IS_OPFS_SUPPORTED,
|
||||
IS_OPUS_SUPPORTED,
|
||||
@ -229,8 +229,13 @@ export function getMessageMediaHash(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const messageKey = getMessageServerKey(message);
|
||||
if (!messageKey) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const mediaId = content.id;
|
||||
const base = `${getMessageKey(message)}${mediaId ? `:${mediaId}` : ''}`;
|
||||
const base = `${messageKey}${mediaId ? `:${mediaId}` : ''}`;
|
||||
|
||||
if (messageVideo) {
|
||||
switch (target) {
|
||||
|
||||
@ -11,7 +11,7 @@ import {
|
||||
SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES, VIDEO_STICKER_MIME_TYPE,
|
||||
} from '../../config';
|
||||
import { areSortedArraysIntersecting, unique } from '../../util/iteratees';
|
||||
import { getMessageKey } from '../../util/messageKey';
|
||||
import { getMessageKey, isLocalMessageId } from '../../util/messageKey';
|
||||
import { getServerTime } from '../../util/serverTime';
|
||||
import { IS_OPUS_SUPPORTED } from '../../util/windowEnvironment';
|
||||
import { getGlobal } from '../index';
|
||||
@ -188,10 +188,6 @@ export function isMessageFailed(message: ApiMessage) {
|
||||
return message.sendingState === 'messageSendingStateFailed';
|
||||
}
|
||||
|
||||
export function isLocalMessageId(id: number) {
|
||||
return !Number.isInteger(id);
|
||||
}
|
||||
|
||||
export function isHistoryClearMessage(message: ApiMessage) {
|
||||
return message.content.action && message.content.action.type === 'historyClear';
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import { IS_MOCKED_CLIENT } from '../config';
|
||||
import { isCacheApiSupported } from '../util/cacheApi';
|
||||
import { getCurrentTabId, reestablishMasterToSelf } from '../util/establishMultitabRole';
|
||||
import { cloneDeep } from '../util/iteratees';
|
||||
import { isLocalMessageId } from '../util/messageKey';
|
||||
import { Bundles, loadBundle } from '../util/moduleLoader';
|
||||
import { parseLocationHash } from '../util/routing';
|
||||
import { clearStoredSession } from '../util/sessions';
|
||||
@ -13,7 +14,6 @@ import { updatePeerColors } from '../util/theme';
|
||||
import { IS_MULTITAB_SUPPORTED } from '../util/windowEnvironment';
|
||||
import { updateTabState } from './reducers/tabs';
|
||||
import { initCache, loadCache } from './cache';
|
||||
import { isLocalMessageId } from './helpers';
|
||||
import {
|
||||
addActionHandler, getGlobal, setGlobal,
|
||||
} from './index';
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import type { ApiMessage, ApiSponsoredMessage, ApiThreadInfo } from '../../api/types';
|
||||
import type { FocusDirection, ThreadId } from '../../types';
|
||||
import type { MessageKey } from '../../util/messageKey';
|
||||
import type {
|
||||
GlobalState, MessageList, MessageListType, TabArgs, TabThread, Thread,
|
||||
} from '../types';
|
||||
@ -13,9 +12,9 @@ import { getCurrentTabId } from '../../util/establishMultitabRole';
|
||||
import {
|
||||
areSortedArraysEqual, excludeSortedArray, omit, pick, pickTruthy, unique,
|
||||
} from '../../util/iteratees';
|
||||
import { isLocalMessageId, type MessageKey } from '../../util/messageKey';
|
||||
import {
|
||||
hasMessageTtl,
|
||||
isLocalMessageId, mergeIdRanges, orderHistoryIds, orderPinnedIds,
|
||||
hasMessageTtl, mergeIdRanges, orderHistoryIds, orderPinnedIds,
|
||||
} from '../helpers';
|
||||
import {
|
||||
selectChat,
|
||||
|
||||
@ -22,7 +22,7 @@ import {
|
||||
import { getCurrentTabId } from '../../util/establishMultitabRole';
|
||||
import { findLast } from '../../util/iteratees';
|
||||
import { MEMO_EMPTY_ARRAY } from '../../util/memo';
|
||||
import { getMessageKey } from '../../util/messageKey';
|
||||
import { getMessageKey, isLocalMessageId } from '../../util/messageKey';
|
||||
import { getServerTime } from '../../util/serverTime';
|
||||
import { IS_TRANSLATION_SUPPORTED } from '../../util/windowEnvironment';
|
||||
import {
|
||||
@ -47,7 +47,6 @@ import {
|
||||
isChatSuperGroup,
|
||||
isCommonBoxChat,
|
||||
isForwardedMessage,
|
||||
isLocalMessageId,
|
||||
isMessageDocumentSticker,
|
||||
isMessageFailed,
|
||||
isMessageLocal,
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import { useEffect, useRef, useState } from '../lib/teact/teact';
|
||||
import {
|
||||
useEffect, useMemo, useRef, useState,
|
||||
} from '../lib/teact/teact';
|
||||
import { getActions, getGlobal } from '../global';
|
||||
|
||||
import type { Track, TrackId } from '../util/audioPlayer';
|
||||
@ -20,7 +22,7 @@ type Handler = (e: Event) => void;
|
||||
const DEFAULT_SKIP_TIME = 10;
|
||||
|
||||
const useAudioPlayer = (
|
||||
trackId: TrackId,
|
||||
trackId: TrackId | undefined,
|
||||
originalDuration: number, // Sometimes incorrect for voice messages
|
||||
trackType: Track['type'],
|
||||
src?: string,
|
||||
@ -50,6 +52,9 @@ const useAudioPlayer = (
|
||||
});
|
||||
|
||||
useSyncEffect(() => {
|
||||
if (!trackId) {
|
||||
return;
|
||||
}
|
||||
controllerRef.current = register(trackId, trackType, (eventName, e) => {
|
||||
if (noHandleEvents) {
|
||||
return;
|
||||
@ -141,11 +146,17 @@ const useAudioPlayer = (
|
||||
requestPreviousTrack,
|
||||
setPlaybackRate,
|
||||
toggleMuted,
|
||||
} = controllerRef.current!;
|
||||
const duration = proxy.duration && Number.isFinite(proxy.duration) ? proxy.duration : originalDuration;
|
||||
} = controllerRef.current ?? {};
|
||||
|
||||
const duration = useMemo(() => {
|
||||
return proxy?.duration && Number.isFinite(proxy.duration) ? proxy.duration : originalDuration;
|
||||
}, [proxy?.duration, originalDuration]);
|
||||
|
||||
// RAF progress
|
||||
useEffect(() => {
|
||||
if (!proxy) {
|
||||
return;
|
||||
}
|
||||
if (noReset && proxy.currentTime === 0) {
|
||||
return;
|
||||
}
|
||||
@ -156,7 +167,7 @@ const useAudioPlayer = (
|
||||
|
||||
// Cleanup
|
||||
useEffect(() => () => {
|
||||
destroy(noPlaylist);
|
||||
destroy?.(noPlaylist);
|
||||
}, [destroy, noPlaylist]);
|
||||
|
||||
// Autoplay once `src` is present
|
||||
@ -166,32 +177,32 @@ const useAudioPlayer = (
|
||||
}
|
||||
|
||||
// When paused by another player
|
||||
if (proxy.src && proxy.paused) {
|
||||
if (proxy?.src && proxy?.paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldPlay && src && !isPlaying) {
|
||||
play(src);
|
||||
play?.(src);
|
||||
}
|
||||
}, [shouldPlay, src, isPlaying, play, proxy.src, proxy.paused, trackType]);
|
||||
}, [shouldPlay, src, isPlaying, play, proxy?.src, proxy?.paused, trackType]);
|
||||
|
||||
const playIfPresent = useLastCallback(() => {
|
||||
if (src) {
|
||||
play(src);
|
||||
play?.(src);
|
||||
}
|
||||
});
|
||||
|
||||
const playPause = useLastCallback(() => {
|
||||
if (isPlaying) {
|
||||
pause();
|
||||
pause?.();
|
||||
} else {
|
||||
playIfPresent();
|
||||
}
|
||||
});
|
||||
|
||||
const setTime = useLastCallback((time: number) => {
|
||||
setCurrentTime(time);
|
||||
if (duration) {
|
||||
setCurrentTime?.(time);
|
||||
if (duration && proxy) {
|
||||
setPlayProgress(proxy.currentTime / duration);
|
||||
}
|
||||
});
|
||||
|
||||
@ -56,6 +56,7 @@ const useBuffering = (noInitiallyBuffered = false, onTimeUpdate?: AnyToVoidFunct
|
||||
});
|
||||
|
||||
const bufferingHandlers = {
|
||||
onPLay: handleBuffering,
|
||||
onLoadedData: handleBuffering,
|
||||
onPlaying: handleBuffering,
|
||||
onLoadStart: handleBuffering, // Needed for Safari to start
|
||||
|
||||
@ -6,7 +6,7 @@ import { AudioOrigin, GlobalSearchContent } from '../types';
|
||||
|
||||
import { requestNextMutation } from '../lib/fasterdom/fasterdom';
|
||||
import { selectCurrentMessageList, selectTabState } from '../global/selectors';
|
||||
import { getMessageKey, parseMessageKey } from './messageKey';
|
||||
import { getMessageServerKey, parseMessageKey } from './messageKey';
|
||||
import { isSafariPatchInProgress, patchSafariProgressiveAudio } from './patchSafariProgressiveAudio';
|
||||
import safePlay from './safePlay';
|
||||
import { IS_SAFARI } from './windowEnvironment';
|
||||
@ -24,6 +24,7 @@ export interface Track {
|
||||
}
|
||||
|
||||
const tracks = new Map<TrackId, Track>();
|
||||
|
||||
let voiceQueue: TrackId[] = [];
|
||||
let musicQueue: TrackId[] = [];
|
||||
|
||||
@ -331,8 +332,12 @@ function findNextInQueue(currentId: TrackId, origin = AudioOrigin.Inline, isReve
|
||||
return chatAudio[index + direction];
|
||||
}
|
||||
|
||||
export function makeTrackId(message: ApiMessage): TrackId {
|
||||
return `${getMessageKey(message)}-${message.date}`;
|
||||
export function makeTrackId(message: ApiMessage): TrackId | undefined {
|
||||
const key = getMessageServerKey(message);
|
||||
if (!key) {
|
||||
return undefined;
|
||||
}
|
||||
return `${key}-${message.date}`;
|
||||
}
|
||||
|
||||
function splitTrackId(trackId: TrackId) {
|
||||
|
||||
@ -8,7 +8,15 @@ export function getMessageKey(message: ApiMessage): MessageKey {
|
||||
return buildMessageKey(chatId, previousLocalId || id);
|
||||
}
|
||||
|
||||
function buildMessageKey(chatId: string, msgId: number): MessageKey {
|
||||
export function getMessageServerKey(message: ApiMessage): MessageKey | undefined {
|
||||
if (isLocalMessageId(message.id)) {
|
||||
return undefined;
|
||||
}
|
||||
const { chatId, id } = message;
|
||||
return buildMessageKey(chatId, id);
|
||||
}
|
||||
|
||||
export function buildMessageKey(chatId: string, msgId: number): MessageKey {
|
||||
return `msg${chatId}-${msgId}`;
|
||||
}
|
||||
|
||||
@ -17,3 +25,7 @@ export function parseMessageKey(key: MessageKey) {
|
||||
|
||||
return { chatId: match[1], messageId: Number(match[2]) };
|
||||
}
|
||||
|
||||
export function isLocalMessageId(id: number) {
|
||||
return !Number.isInteger(id);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user