Add a better solution for 304 browser bug + update naming conventions to better articulate what's happening (#603)

This commit is contained in:
Dan Peterson 2022-01-06 11:49:49 -06:00 committed by GitHub
parent 1eaa172a1b
commit bc38466abf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 53 additions and 41 deletions

View file

@ -13,7 +13,7 @@ import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
import { withRouter } from 'react-router';
import { selectUserVerifiedEmail } from 'redux/selectors/user';
import { selectClientSetting, selectShowMatureContent } from 'redux/selectors/settings';
import { doFetchActiveLivestream } from 'redux/actions/livestream';
import { doFetchChannelLiveStatus } from 'redux/actions/livestream';
import { selectActiveLivestreamForChannel, selectActiveLivestreamInitialized } from 'redux/selectors/livestream';
import { getChannelIdFromClaim } from 'util/claim';
import ChannelContent from './view';
@ -42,7 +42,7 @@ const select = (state, props) => {
const perform = (dispatch) => ({
doResolveUris: (uris, returnCachedUris) => dispatch(doResolveUris(uris, returnCachedUris)),
doFetchActiveLivestream: (channelID) => dispatch(doFetchActiveLivestream(channelID)),
doFetchChannelLiveStatus: (channelID) => dispatch(doFetchChannelLiveStatus(channelID)),
});
export default withRouter(connect(select, perform)(ChannelContent));

View file

@ -37,7 +37,7 @@ type Props = {
doResolveUris: (Array<string>, boolean) => void,
claimType: string,
empty?: string,
doFetchActiveLivestream: (string) => void,
doFetchChannelLiveStatus: (string) => void,
activeLivestreamForChannel: any,
activeLivestreamInitialized: boolean,
};
@ -59,7 +59,7 @@ function ChannelContent(props: Props) {
doResolveUris,
claimType,
empty,
doFetchActiveLivestream,
doFetchChannelLiveStatus,
activeLivestreamForChannel,
activeLivestreamInitialized,
} = props;
@ -126,10 +126,10 @@ function ChannelContent(props: Props) {
// Find out current channels status + active live claim.
React.useEffect(() => {
doFetchActiveLivestream(claimId);
const intervalId = setInterval(() => doFetchActiveLivestream(claimId), 30000);
doFetchChannelLiveStatus(claimId);
const intervalId = setInterval(() => doFetchChannelLiveStatus(claimId), 30000);
return () => clearInterval(intervalId);
}, [claimId, doFetchActiveLivestream]);
}, [claimId, doFetchChannelLiveStatus]);
const showScheduledLiveStreams = claimType !== 'collection'; // ie. not on the playlist page.

View file

@ -477,9 +477,8 @@ export const FETCH_ACTIVE_LIVESTREAMS_FAILED = 'FETCH_ACTIVE_LIVESTREAMS_FAILED'
export const FETCH_ACTIVE_LIVESTREAMS_SKIPPED = 'FETCH_ACTIVE_LIVESTREAMS_SKIPPED';
export const FETCH_ACTIVE_LIVESTREAMS_COMPLETED = 'FETCH_ACTIVE_LIVESTREAMS_COMPLETED';
export const FETCH_ACTIVE_LIVESTREAM_FAILED = 'FETCH_ACTIVE_LIVESTREAMS_FAILED';
export const FETCH_ACTIVE_LIVESTREAM_COMPLETED = 'FETCH_ACTIVE_LIVESTREAM_COMPLETED';
export const FETCH_ACTIVE_LIVESTREAM_FINISHED = 'FETCH_ACTIVE_LIVESTREAM_FINISHED';
export const ADD_CHANNEL_TO_ACTIVE_LIVESTREAMS = 'ADD_CHANNEL_TO_ACTIVE_LIVESTREAMS';
export const REMOVE_CHANNEL_FROM_ACTIVE_LIVESTREAMS = 'REMOVE_CHANNEL_FROM_ACTIVE_LIVESTREAMS';
// Blacklist
export const FETCH_BLACK_LISTED_CONTENT_STARTED = 'FETCH_BLACK_LISTED_CONTENT_STARTED';

View file

@ -7,7 +7,7 @@ import { DISABLE_COMMENTS_TAG } from 'constants/tags';
import { doCommentSocketConnect, doCommentSocketDisconnect } from 'redux/actions/websocket';
import { getChannelIdFromClaim } from 'util/claim';
import { selectActiveLivestreamForChannel, selectActiveLivestreamInitialized } from 'redux/selectors/livestream';
import { doFetchActiveLivestream } from 'redux/actions/livestream';
import { doFetchChannelLiveStatus } from 'redux/actions/livestream';
import LivestreamPage from './view';
const select = (state, props) => {
@ -26,7 +26,7 @@ const perform = {
doUserSetReferrer,
doCommentSocketConnect,
doCommentSocketDisconnect,
doFetchActiveLivestream,
doFetchChannelLiveStatus,
};
export default connect(select, perform)(LivestreamPage);

View file

@ -19,7 +19,7 @@ type Props = {
chatDisabled: boolean,
doCommentSocketConnect: (string, string) => void,
doCommentSocketDisconnect: (string) => void,
doFetchActiveLivestream: (string) => void,
doFetchChannelLiveStatus: (string) => void,
activeLivestreamForChannel: any,
activeLivestreamInitialized: boolean,
};
@ -35,7 +35,7 @@ export default function LivestreamPage(props: Props) {
chatDisabled,
doCommentSocketConnect,
doCommentSocketDisconnect,
doFetchActiveLivestream,
doFetchChannelLiveStatus,
activeLivestreamForChannel,
activeLivestreamInitialized,
} = props;
@ -67,10 +67,10 @@ export default function LivestreamPage(props: Props) {
// Find out current channels status + active live claim.
React.useEffect(() => {
doFetchActiveLivestream(livestreamChannelId);
const intervalId = setInterval(() => doFetchActiveLivestream(livestreamChannelId), 30000);
doFetchChannelLiveStatus(livestreamChannelId);
const intervalId = setInterval(() => doFetchChannelLiveStatus(livestreamChannelId), 30000);
return () => clearInterval(intervalId);
}, [livestreamChannelId, doFetchActiveLivestream]);
}, [livestreamChannelId, doFetchChannelLiveStatus]);
const [activeStreamUri, setActiveStreamUri] = React.useState(false);

View file

@ -4,6 +4,16 @@ import { doClaimSearch } from 'redux/actions/claims';
import { LIVESTREAM_LIVE_API, LIVESTREAM_STARTS_SOON_BUFFER } from 'constants/livestream';
import moment from 'moment';
const LiveStatus = Object.freeze({
LIVE: 'LIVE',
NOT_LIVE: 'NOT_LIVE',
UNKNOWN: 'UNKNOWN',
});
type LiveStatusType = $Keys<typeof LiveStatus>;
type LiveChannelStatus = { channelStatus: LiveStatusType, channelData?: LivestreamInfo };
export const doFetchNoSourceClaims = (channelId: string) => async (dispatch: Dispatch, getState: GetState) => {
dispatch({
type: ACTIONS.FETCH_NO_SOURCE_CLAIMS_STARTED,
@ -48,23 +58,22 @@ const transformLivestreamData = (data: Array<any>): LivestreamInfo => {
}, {});
};
const fetchLiveChannels = async () => {
const fetchLiveChannels = async (): Promise<LivestreamInfo> => {
const response = await fetch(LIVESTREAM_LIVE_API);
const json = await response.json();
if (!json.data) throw new Error();
return transformLivestreamData(json.data);
};
const fetchLiveChannel = async (channelId: string) => {
const response = await fetch(`${LIVESTREAM_LIVE_API}/${channelId}`);
let json;
const fetchLiveChannel = async (channelId: string): Promise<LiveChannelStatus> => {
try {
json = await response.json();
const response = await fetch(`${LIVESTREAM_LIVE_API}/${channelId}`);
const json = await response.json();
if (json.data?.live === false) return { channelStatus: LiveStatus.NOT_LIVE };
return { channelStatus: LiveStatus.LIVE, channelData: transformLivestreamData([json.data]) };
} catch {
throw new Error('Error handling live API response');
return { channelStatus: LiveStatus.UNKNOWN };
}
if (!(json.data && json.data.live)) throw new Error();
return transformLivestreamData([json.data]);
};
const filterUpcomingLiveStreamClaims = (upcomingClaims) => {
@ -164,25 +173,29 @@ const findActiveStreams = async (channelIDs: Array<string>, orderBy: Array<strin
return determineLiveClaim(allClaims, liveChannels);
};
export const doFetchActiveLivestream = (channelId: string) => {
export const doFetchChannelLiveStatus = (channelId: string) => {
return async (dispatch: Dispatch) => {
try {
const liveChannel = await fetchLiveChannel(channelId);
const currentlyLiveClaims = await findActiveStreams([channelId], ['release_time'], liveChannel, dispatch);
const { channelStatus, channelData } = await fetchLiveChannel(channelId);
if (channelStatus === LiveStatus.NOT_LIVE) {
dispatch({ type: ACTIONS.REMOVE_CHANNEL_FROM_ACTIVE_LIVESTREAMS, data: { channelId } });
return;
}
if (channelStatus === LiveStatus.UNKNOWN) {
return;
}
const currentlyLiveClaims = await findActiveStreams([channelId], ['release_time'], channelData, dispatch);
const liveClaim = currentlyLiveClaims[channelId];
liveChannel[channelId].claimId = liveClaim.stream.claim_id;
liveChannel[channelId].claimUri = liveClaim.stream.canonical_url;
dispatch({
type: ACTIONS.FETCH_ACTIVE_LIVESTREAM_COMPLETED,
data: {
...liveChannel,
},
});
if (channelData && liveClaim) {
channelData[channelId].claimId = liveClaim.stream.claim_id;
channelData[channelId].claimUri = liveClaim.stream.canonical_url;
dispatch({ type: ACTIONS.ADD_CHANNEL_TO_ACTIVE_LIVESTREAMS, data: { ...channelData } });
}
} catch (err) {
if (err.message === 'Error handling live API response') return;
dispatch({ type: ACTIONS.FETCH_ACTIVE_LIVESTREAM_FAILED, data: { channelId } });
dispatch({ type: ACTIONS.REMOVE_CHANNEL_FROM_ACTIVE_LIVESTREAMS, data: { channelId } });
}
};
};

View file

@ -58,11 +58,11 @@ export default handleActions(
activeLivestreamsLastFetchedOptions,
};
},
[ACTIONS.FETCH_ACTIVE_LIVESTREAM_COMPLETED]: (state: LivestreamState, action: any) => {
[ACTIONS.ADD_CHANNEL_TO_ACTIVE_LIVESTREAMS]: (state: LivestreamState, action: any) => {
const activeLivestreams = Object.assign({}, state.activeLivestreams || {}, action.data);
return { ...state, activeLivestreams, activeLivestreamInitialized: true };
},
[ACTIONS.FETCH_ACTIVE_LIVESTREAM_FAILED]: (state: LivestreamState, action: any) => {
[ACTIONS.REMOVE_CHANNEL_FROM_ACTIVE_LIVESTREAMS]: (state: LivestreamState, action: any) => {
const activeLivestreams = state.activeLivestreams;
if (activeLivestreams) delete activeLivestreams[action.data.channelId];
return { ...state, activeLivestreams: Object.assign({}, activeLivestreams), activeLivestreamInitialized: true };