Skip to content

Commit

Permalink
refactor: filtering in the default renderer component
Browse files Browse the repository at this point in the history
  • Loading branch information
AXeL-dev committed Nov 7, 2022
1 parent b0b3279 commit e9e662b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 27 deletions.
18 changes: 10 additions & 8 deletions src/store/selectors/videos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@ export const selectChannelVideosById = (
channel: Channel,
filterCallback: (video: VideoCache) => boolean = () => true,
) =>
createSelector(selectChannelVideos(channel), (videos) =>
videos.filter(filterCallback).reduce(
(acc, video) => ({
...acc,
[video.id]: video,
}),
{},
),
createSelector(
selectChannelVideos(channel),
(videos) =>
videos.filter(filterCallback).reduce(
(acc, video) => ({
...acc,
[video.id]: video,
}),
{},
) as { [key: string]: VideoCache },
);

export const selectUnflaggedVideos = (channel?: Channel) =>
Expand Down
26 changes: 21 additions & 5 deletions src/ui/components/pages/Home/ChannelRenderer/AllViewRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';
import { useAppSelector } from 'store';
import {
selectVideosSeniority,
Expand All @@ -7,7 +7,8 @@ import {
import { date2ISO, getDateBefore } from 'helpers/utils';
import DefaultRenderer, { DefaultRendererProps } from './DefaultRenderer';
import { selectChannelVideosById } from 'store/selectors/videos';
import { HomeView, VideosSeniority } from 'types';
import { HomeView, Video, VideoCache, VideosSeniority } from 'types';
import { filterVideoByFlags } from 'store/services/youtube';
import { jsonEqualityFn } from 'store/utils';

export interface AllViewRendererProps
Expand All @@ -19,14 +20,30 @@ const persistVideosOptions = {
flags: { recent: true },
};

const filterableFlags = [
'seen',
'toWatchLater',
'archived',
'ignored',
'bookmarked',
];

const videosCacheFilter = ({ flags }: VideoCache) =>
Object.keys(flags).some((flag) => filterableFlags.includes(flag));

function AllViewRenderer(props: AllViewRendererProps) {
const { channel } = props;
const filters = useAppSelector(selectViewFilters(HomeView.All));
const videosSeniority = useAppSelector(selectVideosSeniority(HomeView.All));
const videos = useAppSelector(
selectChannelVideosById(channel),
selectChannelVideosById(channel, videosCacheFilter),
jsonEqualityFn,
);
const filterCallback = useCallback(
({ id }: Video) =>
videos[id] ? filterVideoByFlags(videos[id], filters) : filters.others,
[filters, videos],
);
const publishedAfter = useMemo(
() =>
videosSeniority === VideosSeniority.Any
Expand All @@ -39,8 +56,7 @@ function AllViewRenderer(props: AllViewRendererProps) {
<DefaultRenderer
publishedAfter={publishedAfter}
persistVideosOptions={persistVideosOptions}
cachedVideos={videos}
filters={filters}
filter={filterCallback}
{...props}
/>
);
Expand Down
22 changes: 8 additions & 14 deletions src/ui/components/pages/Home/ChannelRenderer/DefaultRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
import { Channel, HomeView, Video, VideoCache, ViewFilters } from 'types';
import { Channel, HomeView, Video } from 'types';
import {
PersistVideosOptions,
useGetChannelVideosQuery,
Expand All @@ -8,27 +8,27 @@ import ChannelRenderer from './ChannelRenderer';
import config from './ChannelVideos/config';
import { useGrid } from 'hooks';
import { useChannelVideos } from 'providers';
import { filterVideoByFlags } from 'store/services/youtube';

export interface DefaultRendererProps {
view: HomeView;
channel: Channel;
publishedAfter?: string;
persistVideosOptions?: PersistVideosOptions;
cachedVideos?: { [key: string]: VideoCache };
filters?: ViewFilters;
filter?: (video: Video) => boolean;
onError?: (error: any) => void;
onVideoPlay: (video: Video) => void;
}

// should be instanciated outside the component to avoid multi-rendering
const defaultFilter = () => true;

function DefaultRenderer(props: DefaultRendererProps) {
const {
view,
channel,
publishedAfter,
persistVideosOptions,
cachedVideos,
filters,
filter = defaultFilter,
onError,
...rest
} = props;
Expand Down Expand Up @@ -59,13 +59,7 @@ function DefaultRenderer(props: DefaultRendererProps) {
}),
},
);
let videos = data?.items || [];
if (filters && cachedVideos) {
videos = videos.filter(({ id }) =>
cachedVideos[id] ? filterVideoByFlags(cachedVideos[id], filters) : true,
);
}

const videos = (data?.items || []).filter(filter);
const count = data?.count || 0;
const total = data?.total || 0;

Expand All @@ -85,7 +79,7 @@ function DefaultRenderer(props: DefaultRendererProps) {
setChannelData({ channel, items: videos, total });
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFetching, data, cachedVideos, filters]);
}, [isFetching, data, filter]);

return (
<ChannelRenderer
Expand Down

0 comments on commit e9e662b

Please sign in to comment.