182 lines
5 KiB
JavaScript
182 lines
5 KiB
JavaScript
// @flow
|
|
import { createSelector } from 'reselect';
|
|
import {
|
|
makeSelectClaimForUri,
|
|
selectClaimsByUri,
|
|
makeSelectClaimsInChannelForCurrentPageState,
|
|
makeSelectClaimIsNsfw,
|
|
makeSelectRecommendedContentForUri,
|
|
makeSelectMediaTypeForUri,
|
|
selectBlockedChannels,
|
|
parseURI,
|
|
} from 'lbry-redux';
|
|
import { selectAllCostInfoByUri } from 'lbryinc';
|
|
import { selectShowMatureContent } from 'redux/selectors/settings';
|
|
|
|
const RECENT_HISTORY_AMOUNT = 10;
|
|
const HISTORY_ITEMS_PER_PAGE = 50;
|
|
|
|
export const selectState = (state: any) => state.content || {};
|
|
|
|
export const selectPlayingUri = createSelector(
|
|
selectState,
|
|
state => state.playingUri
|
|
);
|
|
|
|
export const makeSelectIsPlaying = (uri: string) =>
|
|
createSelector(
|
|
selectPlayingUri,
|
|
playingUri => playingUri === uri
|
|
);
|
|
|
|
export const makeSelectContentPositionForUri = (uri: string) =>
|
|
createSelector(
|
|
selectState,
|
|
makeSelectClaimForUri(uri),
|
|
(state, claim) => {
|
|
if (!claim) {
|
|
return null;
|
|
}
|
|
const outpoint = `${claim.txid}:${claim.nout}`;
|
|
const id = claim.claim_id;
|
|
return state.positions[id] ? state.positions[id][outpoint] : null;
|
|
}
|
|
);
|
|
|
|
export const selectHistory = createSelector(
|
|
selectState,
|
|
state => state.history || []
|
|
);
|
|
|
|
export const selectHistoryPageCount = createSelector(
|
|
selectHistory,
|
|
history => Math.ceil(history.length / HISTORY_ITEMS_PER_PAGE)
|
|
);
|
|
|
|
export const makeSelectHistoryForPage = (page: number) =>
|
|
createSelector(
|
|
selectHistory,
|
|
selectClaimsByUri,
|
|
(history, claimsByUri) => {
|
|
const left = page * HISTORY_ITEMS_PER_PAGE;
|
|
const historyItemsForPage = history.slice(left, left + HISTORY_ITEMS_PER_PAGE);
|
|
return historyItemsForPage;
|
|
}
|
|
);
|
|
|
|
export const makeSelectHistoryForUri = (uri: string) =>
|
|
createSelector(
|
|
selectHistory,
|
|
history => history.find(i => i.uri === uri)
|
|
);
|
|
|
|
export const makeSelectHasVisitedUri = (uri: string) =>
|
|
createSelector(
|
|
makeSelectHistoryForUri(uri),
|
|
history => Boolean(history)
|
|
);
|
|
|
|
export const makeSelectNextUnplayedRecommended = (uri: string) =>
|
|
createSelector(
|
|
makeSelectRecommendedContentForUri(uri),
|
|
selectHistory,
|
|
selectClaimsByUri,
|
|
selectAllCostInfoByUri,
|
|
selectBlockedChannels,
|
|
(
|
|
recommendedForUri: Array<string>,
|
|
history: Array<{ uri: string }>,
|
|
claimsByUri: { [string]: ?Claim },
|
|
costInfoByUri: { [string]: { cost: 0 | string } },
|
|
blockedChannels: Array<string>
|
|
) => {
|
|
if (recommendedForUri) {
|
|
// Make sure we don't autoplay paid content, channels, or content from blocked channels
|
|
for (let i = 0; i < recommendedForUri.length; i++) {
|
|
const recommendedUri = recommendedForUri[i];
|
|
const claim = claimsByUri[recommendedUri];
|
|
|
|
if (!claim) {
|
|
continue;
|
|
}
|
|
|
|
const { isChannel } = parseURI(recommendedUri);
|
|
if (isChannel) {
|
|
continue;
|
|
}
|
|
|
|
const costInfo = costInfoByUri[recommendedUri];
|
|
if (!costInfo || costInfo.cost !== 0) {
|
|
continue;
|
|
}
|
|
|
|
// We already check if it's a channel above
|
|
// $FlowFixMe
|
|
const isVideo = claim.value && claim.value.stream_type === 'video';
|
|
// $FlowFixMe
|
|
const isAudio = claim.value && claim.value.stream_type === 'audio';
|
|
if (!isVideo && !isAudio) {
|
|
continue;
|
|
}
|
|
|
|
const channel = claim && claim.signing_channel;
|
|
if (channel && blockedChannels.some(blockedUri => blockedUri === channel.permanent_url)) {
|
|
continue;
|
|
}
|
|
|
|
if (!history.some(item => item.uri === recommendedForUri[i])) {
|
|
return recommendedForUri[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
export const selectRecentHistory = createSelector(
|
|
selectHistory,
|
|
history => {
|
|
return history.slice(0, RECENT_HISTORY_AMOUNT);
|
|
}
|
|
);
|
|
|
|
export const makeSelectCategoryListUris = (uris: ?Array<string>, channel: string) =>
|
|
createSelector(
|
|
makeSelectClaimsInChannelForCurrentPageState(channel),
|
|
channelClaims => {
|
|
if (uris) return uris;
|
|
|
|
if (channelClaims) {
|
|
const CATEGORY_LIST_SIZE = 10;
|
|
return channelClaims.slice(0, CATEGORY_LIST_SIZE).map(({ name, claim_id: claimId }) => `${name}#${claimId}`);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
);
|
|
|
|
export const makeSelectShouldObscurePreview = (uri: string) =>
|
|
createSelector(
|
|
selectShowMatureContent,
|
|
makeSelectClaimIsNsfw(uri),
|
|
(showMatureContent, isClaimMature) => {
|
|
return isClaimMature && !showMatureContent;
|
|
}
|
|
);
|
|
|
|
export const makeSelectCanAutoplay = (uri: string) =>
|
|
createSelector(
|
|
makeSelectMediaTypeForUri(uri),
|
|
mediaType => {
|
|
const canAutoPlay = ['audio', 'video', 'image', 'text', 'document'].includes(mediaType);
|
|
return canAutoPlay;
|
|
}
|
|
);
|
|
|
|
export const makeSelectIsText = (uri: string) =>
|
|
createSelector(
|
|
makeSelectMediaTypeForUri(uri),
|
|
mediaType => {
|
|
const isText = ['document', 'script'].includes(mediaType);
|
|
return isText;
|
|
}
|
|
);
|