// @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, history: Array<{ uri: string }>, claimsByUri: { [string]: ?Claim }, costInfoByUri: { [string]: { cost: 0 | string } }, blockedChannels: Array ) => { 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, 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 = ['text', 'document', 'script'].includes(mediaType); return isText; } );