Skip to content

Instantly share code, notes, and snippets.

@Belobobr
Created May 19, 2018 21:13
Show Gist options
  • Select an option

  • Save Belobobr/7648cc16b3c99918d1abbc9496b4632e to your computer and use it in GitHub Desktop.

Select an option

Save Belobobr/7648cc16b3c99918d1abbc9496b4632e to your computer and use it in GitHub Desktop.
Selectors
// @flow
/* Channels */
import {createSelector} from 'reselect'
import t from '../../localization/index';
import type {State} from "../../reducers/index";
import type {MostWatchedChannel} from "../../reducers/channels";
import type {
AllChannelsDeviation,
FilterValues,
MostPopularChannelsDeviation,
MostWatchedChannelsDeviation,
PromotedChannelsDeviation,
RecentlyWatchedChannelsDeviation,
SearchedChannelsDeviation,
TvChannelsDeviation,
TvChannelsFiltersDeviation,
WatchingTvChannelDeviation
} from "./TypeDefenition";
import type {
CategoryFilter,
Channel,
CountryFilter,
GenreFilter,
LanguageFilter,
TvChannelsFilter
} from "../../entities";
import {DATE, NUMBER, RATING} from "../../constants/filterTypes";
import type {EntityFiltersState} from "../../reducers/filters";
const TOP_CHANNELS_LIMIT = 20;
const LAST_ADDED_CHANNELS_LIMIT = 20;
function isFavoriteTvChannel(id: string, favoritesIds: Array<string>) {
return favoritesIds.indexOf(id) >= 0;
}
export const getSelectedFilter = (state: State) => state.channels.tv.selectedFilter;
export const getChannelsMap = (state: State) => state.channels.tv.channelsMap;
export const getAllChannelsIds = (state: State) => state.channels.tv.allChannelsIds;
export const getFavoritesChannelsIds = (state: State) => state.channels.tv.favoritesIds;
export const getRecentlyWatchedIds = (state: State) => state.channels.tv.recentlyWatchedIds;
export const getSearchedChannels = createSelector(
[getSelectedFilter, getChannelsMap, getAllChannelsIds],
(selectedFilter, channelsMap, allChannelsIds): SearchedChannelsDeviation => {
const searchText = selectedFilter.searchText.toLowerCase();
console.log('Searched channels selector: ' + searchText);
return allChannelsIds
.map(id => channelsMap[id])
.filter(channel => channel.title.toLowerCase().includes(searchText));
}
);
export const getMostPopularChannels = createSelector(
[getChannelsMap, getAllChannelsIds],
(channelsMap, allChannelsIds): MostPopularChannelsDeviation => {
console.log('Most popular channels selector');
return allChannelsIds
.map(id => channelsMap[id])
.sort((a, b) => b.rating - a.rating)
.slice(0, TOP_CHANNELS_LIMIT);
}
);
export const getLastAddedChannels = createSelector(
[getChannelsMap, getAllChannelsIds],
(channelsMap, allChannelsIds) => {
console.log('Last added channels selector');
return allChannelsIds
.map(id => channelsMap[id])
.sort((a, b) => Date.parse(b.created) - Date.parse(a.created))
.slice(0, LAST_ADDED_CHANNELS_LIMIT);
}
);
export const getRecentlyWatchedChannels = createSelector(
[getChannelsMap, getRecentlyWatchedIds],
(channelsMap, recentlyWatchedIds): RecentlyWatchedChannelsDeviation => {
console.log('Recently watched channels selector');
return recentlyWatchedIds
.map(id => channelsMap[id])
.filter(channel => !!channel);
}
);
const getMostWatchedChannelsRow = (state: State) => state.channels.tv.mostWatchedChannels;
export const getMostWatchedChannels = createSelector(
[getChannelsMap, getMostWatchedChannelsRow],
(channelsMap, mostWatchedChannelsRow): MostWatchedChannelsDeviation => {
console.log('Most watched channels selector');
return mostWatchedChannelsRow
.map((mostWatchedChannel: MostWatchedChannel) => channelsMap[mostWatchedChannel._id])
.filter(channel => !!channel);
}
);
export const getPromotedTvChannels = createSelector(
[getRecentlyWatchedChannels, getMostPopularChannels, getMostWatchedChannels],
(recentlyWatchedChannels, mostPopularChannels, mostWatchedChannels): PromotedChannelsDeviation => {
console.log('Promoted channels selector');
let promotedChannelsSet = {};
return mostWatchedChannels
.concat(recentlyWatchedChannels)
.concat(mostPopularChannels)
.filter(channel => {
if (promotedChannelsSet[channel._id] === undefined) {
promotedChannelsSet[channel._id] = true;
return true
} else {
return false
}
})
.slice(0, 20);
}
);
export const getAllChannels = createSelector(
[getSelectedFilter, getChannelsMap, getAllChannelsIds],
(selectedFilter: TvChannelsFilter, channelsMap, allChannelsIds): AllChannelsDeviation => {
console.log('All channels selector');
let allChannels = allChannelsIds
.map(id => channelsMap[id])
.filter(channel => selectedFilter.category === null || channel.categories.includes(selectedFilter.category))
.filter(channel => selectedFilter.country === null || channel.countries.includes(selectedFilter.country))
.filter(channel => selectedFilter.genre === null || channel.genres.includes(selectedFilter.genre))
.filter(channel => selectedFilter.language === null || channel.languages.includes(selectedFilter.language));
switch (selectedFilter.sortBy) {
case RATING:
allChannels.sort((a, b) => b.rating - a.rating);
break;
case NUMBER:
allChannels.sort((a, b) => a.number - b.number);
break;
case DATE:
allChannels.sort((a, b) => Date.parse(b.created) - Date.parse(a.created));
break;
}
return allChannels;
}
);
const getChannelsFiltersRow = (state: State): EntityFiltersState => state.filters.channels;
export const getTvChannelsFilters = createSelector(
[getChannelsFiltersRow, getAllChannels],
(channelsFilters: EntityFiltersState, allChannels: AllChannelsDeviation): TvChannelsFiltersDeviation => {
console.log('Tv channels filters selector');
let channelsFiltersState: EntityFiltersState = channelsFilters;
let availableCategoriesIds: Set<string> = new Set();
let availableGenresIds: Set<string> = new Set();
let availableLanguagesIds: Set<string> = new Set();
let availableCountriesIds: Set<string> = new Set();
allChannels.forEach((channel: Channel) => {
channel.categories.forEach(categoryId => {
availableCategoriesIds.add(categoryId);
});
channel.genres.forEach(genreId => {
availableGenresIds.add(genreId);
});
channel.languages.forEach(languageId => {
availableLanguagesIds.add(languageId);
});
channel.countries.forEach(countryId => {
availableCountriesIds.add(countryId);
});
});
let availableCategories: Array<FilterValues> = channelsFiltersState.category.data
.map((categoryFilter: CategoryFilter) => ({
_id: categoryFilter._id,
title: categoryFilter.title,
active: availableCategoriesIds.has(categoryFilter._id)
}));
let availableGenres: Array<FilterValues> = channelsFiltersState.genre.data
.map((genreFitler: GenreFilter) => ({
_id: genreFitler._id,
title: genreFitler.title,
active: availableGenresIds.has(genreFitler._id)
}));
let availableLanguages: Array<FilterValues> = channelsFiltersState.language.data
.map((languageFilter: LanguageFilter) => ({
_id: languageFilter._id,
title: languageFilter.name,
active: availableLanguagesIds.has(languageFilter._id)
}));
let availableCountries: Array<FilterValues> = channelsFiltersState.country.data
.map((countryFilter: CountryFilter) => ({
_id: countryFilter._id,
title: countryFilter.commonName,
active: availableLanguagesIds.has(countryFilter._id)
}));
return {
category: availableCategories.length > 0 ? {title: t.category, values: availableCategories} : null,
genre: availableGenres.length > 0 ? {title: t.genre, values: availableGenres} : null,
language: availableLanguages.length > 0 ? {title: t.language, values: availableLanguages} : null,
country: availableCountries.length > 0 ? {title: t.country, values: availableCountries} : null,
sortBy: {
title: t.sort,
values: [
{_id: RATING, title: t.by_rating, active: true},
{_id: NUMBER, title: t.by_number, active: true},
{_id: DATE, title: t.by_date, active: true}
]
},
};
}
);
export const getFavoritesChannels = createSelector(
[getChannelsMap, getFavoritesChannelsIds],
(channelsMap, favoritesChannelsIds) => {
console.log('Favorites channels selector');
return favoritesChannelsIds
.map(id => channelsMap[id])
.filter(channel => !!channel);
}
);
export const getTvChannels = createSelector(
[
getSelectedFilter,
getChannelsMap,
getAllChannels,
getFavoritesChannels,
getRecentlyWatchedChannels,
getLastAddedChannels,
getMostPopularChannels,
getPromotedTvChannels,
getSearchedChannels
], (selectedFilter,
channelsMap,
allChannels,
favoritesChannels,
recentlyWatched,
mostPopularChannels,
lastAddedChannels,
promotedTvChannels,
searchedChannels): TvChannelsDeviation => {
return {
allChannels,
favoritesChannels,
recentlyWatched,
mostPopularChannels,
lastAddedChannels,
promotedTvChannels,
searchedChannels
}
}
);
const getWatchingChannel = (state: State) => state.channels.tv.watchingChannel;
const getChannelsSources = (state: State) => state.channels.tv.channelsSources;
export const getWatchingTvChannel = createSelector(
[getWatchingChannel, getChannelsMap, getFavoritesChannelsIds, getChannelsSources],
(watchingChannel, channelsMap, favoritesChannelsIds, channelsSources): WatchingTvChannelDeviation => {
console.log('Watching channel selector');
const watchingChannelId = watchingChannel !== null ? watchingChannel._id : null;
const isFavorite = favoritesChannelsIds.indexOf(watchingChannelId) >= 0;
return {
...channelsMap[watchingChannelId],
isFavorite,
sources: channelsSources[watchingChannelId]
}
}
);
import {createSelector} from 'reselect'
import t from '../../localization/index';
import type {State} from "../../reducers/index";
import type {MovieOwnProps} from "../../components/movies/MovieDetailsScreen";
import type {MovieDeviation, MoviesDeviation, MoviesFiltersDeviation} from "./TypeDefenition";
/* Movies */
function isFavoriteMovie(id: string, favoritesIds: Array<string>) {
return favoritesIds.indexOf(id) >= 0;
}
export const getSelectedFilter = (state: State) => state.movies.selectedFilter;
export const getAllMoviesIds = (state: State) => state.movies.all.ids;
export const getFavoritesMoviesIds = (state: State) => state.movies.favoritesIds;
export const getLastAddedMoviesIds = (state: State) => state.movies.lastAdded.data;
export const getTopMoviesIds = (state: State) => state.movies.top.data;
export const getMoviesMap = (state: State) => state.movies.all.map;
export const getMovies = createSelector(
[getAllMoviesIds, getFavoritesMoviesIds, getLastAddedMoviesIds, getTopMoviesIds, getMoviesMap],
(allMoviesIds, favoritesMoviesIds, lastAddedMoviesIds, topMoviesIds, moviesMap): MoviesDeviation => {
let all =
allMoviesIds
.map(id => moviesMap[id])
.map(movie => ({...movie, isFavorite: isFavoriteMovie(movie._id, favoritesMoviesIds)}));
let lastAdded =
lastAddedMoviesIds
.map(id => moviesMap[id])
.map(movie => ({...movie, isFavorite: isFavoriteMovie(movie._id, favoritesMoviesIds)}));
let top =
topMoviesIds
.map(id => moviesMap[id])
.map(movie => ({...movie, isFavorite: isFavoriteMovie(movie._id, favoritesMoviesIds)}));
let favorites =
favoritesMoviesIds
.map(id => moviesMap[id])
.map(movie => ({...movie, isFavorite: true}));
return {
all,
lastAdded,
top,
favorites
}
}
);
export const getMovieRow = (state: State, props: MovieOwnProps) => state.movies.all[props.navigation.state.params.movieId];
export const getMovie = createSelector(
[getFavoritesMoviesIds, getMovieRow],
(favoritesMoviesIds, movieRow): MovieDeviation => {
return {
...movieRow,
isFavorite: isFavoriteMovie(movieRow._id, favoritesMoviesIds)
}
}
);
const getMoviesFiltersRow = (state: State) => state.filters.movies;
export const getMoviesFilters = createSelector(
[getMoviesFiltersRow],
(channelsFilters): MoviesFiltersDeviation => {
console.log('Movies filters selector');
let filters = channelsFilters;
const titleForFilterType = {
category: 'title',
genre: 'title',
language: 'name',
country: 'commonName'
};
let tvChannelsFilters = {
category: {title: t.category, values: []},
genre: {title: t.genre, values: []},
language: {title: t.language, values: []},
country: {title: t.country, values: []}
};
Object.keys(tvChannelsFilters).forEach(filterId => {
tvChannelsFilters[filterId].values = filters[filterId].data.map(value => ({
_id: value._id,
title: value[titleForFilterType[filterId]],
active: true
}))
});
return tvChannelsFilters
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment