Media: Fix stuck loading after page refresh (#4575)

This commit is contained in:
Alexander Zinchuk 2024-05-14 04:23:48 +02:00
parent c15c8a0eed
commit c610c5ca73
5 changed files with 30 additions and 9 deletions

View File

@ -134,3 +134,7 @@ export function selectCanAnimateInterface<T extends GlobalState>(global: T) {
export function selectIsContextMenuTranslucent<T extends GlobalState>(global: T) {
return selectPerformanceSettingsValue(global, 'contextMenuBlur');
}
export function selectIsSynced<T extends GlobalState>(global: T) {
return global.isSynced;
}

View File

@ -2,8 +2,10 @@ import { useEffect } from '../lib/teact/teact';
import { ApiMediaFormat } from '../api/types';
import { selectIsSynced } from '../global/selectors';
import * as mediaLoader from '../util/mediaLoader';
import useForceUpdate from './useForceUpdate';
import useSelector from './useSelector';
const useMedia = (
mediaHash: string | false | undefined,
@ -13,9 +15,10 @@ const useMedia = (
) => {
const mediaData = mediaHash ? mediaLoader.getFromMemory(mediaHash) : undefined;
const forceUpdate = useForceUpdate();
const isSynced = useSelector(selectIsSynced);
useEffect(() => {
if (!noLoad && mediaHash && !mediaData) {
if (isSynced && !noLoad && mediaHash && !mediaData) {
const startedAt = Date.now();
mediaLoader.fetch(mediaHash, mediaFormat).then(() => {
@ -27,7 +30,7 @@ const useMedia = (
}
});
}
}, [noLoad, mediaHash, mediaData, mediaFormat, forceUpdate, delay]);
}, [noLoad, mediaHash, mediaData, mediaFormat, delay, isSynced]);
return mediaData;
};

View File

@ -4,10 +4,12 @@ import {
import { ApiMediaFormat } from '../api/types';
import { selectIsSynced } from '../global/selectors';
import * as mediaLoader from '../util/mediaLoader';
import { throttle } from '../util/schedulers';
import { IS_PROGRESSIVE_SUPPORTED } from '../util/windowEnvironment';
import useForceUpdate from './useForceUpdate';
import useSelector from './useSelector';
import useUniqueId from './useUniqueId';
const STREAMING_PROGRESS = 0.75;
@ -24,6 +26,7 @@ export default function useMediaWithLoadProgress(
const mediaData = mediaHash ? mediaLoader.getFromMemory(mediaHash) : undefined;
const isStreaming = IS_PROGRESSIVE_SUPPORTED && mediaFormat === ApiMediaFormat.Progressive;
const forceUpdate = useForceUpdate();
const isSynced = useSelector(selectIsSynced);
const id = useUniqueId();
const [loadProgress, setLoadProgress] = useState(mediaData && !isStreaming ? 1 : 0);
const startedAtRef = useRef<number>();
@ -37,7 +40,7 @@ export default function useMediaWithLoadProgress(
}, [delay]);
useEffect(() => {
if (!noLoad && mediaHash) {
if (isSynced && !noLoad && mediaHash) {
if (!mediaData) {
setLoadProgress(0);
@ -64,7 +67,7 @@ export default function useMediaWithLoadProgress(
}
}
}, [
noLoad, mediaHash, mediaData, mediaFormat, forceUpdate, isStreaming, delay, handleProgress, isHtmlAllowed, id,
noLoad, mediaHash, mediaData, mediaFormat, isStreaming, delay, handleProgress, isHtmlAllowed, id, isSynced,
]);
useEffect(() => {

11
src/hooks/useSelector.ts Normal file
View File

@ -0,0 +1,11 @@
import type { GlobalState } from '../global/types';
import useDerivedState from './useDerivedState';
import useSelectorSignal from './useSelectorSignal';
type Selector<T extends unknown> = (global: GlobalState) => T;
export default function useSelector<T extends unknown>(selector: Selector<T>) {
const selectorSignal = useSelectorSignal(selector);
return useDerivedState(selectorSignal);
}

View File

@ -13,15 +13,15 @@ import useEffectOnce from './useEffectOnce';
b) Return a signal instead of forcing a component update right away.
*/
type Selector<T extends any> = (global: GlobalState) => T;
type Selector<T extends unknown> = (global: GlobalState) => T;
interface State<T extends any> {
interface State<T extends unknown> {
clientsCount: number;
getter: Signal<T>;
setter: SignalSetter;
}
const bySelector = new Map<Selector<any>, State<any>>();
const bySelector = new Map<Selector<unknown>, State<unknown>>();
addCallback((global: GlobalState) => {
for (const [selector, { setter }] of bySelector) {
@ -29,7 +29,7 @@ addCallback((global: GlobalState) => {
}
});
function useSelectorSignal<T extends any>(selector: Selector<T>): Signal<T> {
function useSelectorSignal<T extends unknown>(selector: Selector<T>): Signal<T> {
let state = bySelector.get(selector);
if (!state) {
@ -50,7 +50,7 @@ function useSelectorSignal<T extends any>(selector: Selector<T>): Signal<T> {
};
});
return state.getter;
return state.getter as Signal<T>;
}
export default useSelectorSignal;