Skip to content

Commit

Permalink
feat: add display options to home page
Browse files Browse the repository at this point in the history
  • Loading branch information
AXeL-dev committed May 20, 2022
1 parent f118a47 commit 3939228
Show file tree
Hide file tree
Showing 12 changed files with 283 additions and 40 deletions.
38 changes: 35 additions & 3 deletions src/store/reducers/settings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { HomeView, Settings, VideosSeniority, ViewFilters } from 'types';
import {
HomeDisplayOptions,
HomeView,
Settings,
VideosSeniority,
ViewFilters,
} from 'types';

const { REACT_APP_YOUTUBE_API_KEY } = process.env;

Expand All @@ -19,9 +25,14 @@ export const defaultSettings = {
viewed: true,
archived: true,
},
homeDisplayOptions: {
hiddenViews: [],
},
enableNotifications: true,
};

const views = Object.values(HomeView);

interface SettingsState extends Settings {}

const initialState: SettingsState = {
Expand Down Expand Up @@ -73,10 +84,31 @@ export const settingsSlice = createSlice({
return state;
}
},
setHomeDisplayOptions: (
state,
action: PayloadAction<Partial<HomeDisplayOptions>>
) => {
const { hiddenViews } = action.payload;
return {
...state,
defaultView:
!state.defaultView || hiddenViews?.includes(state.defaultView)
? views.find((view) => !hiddenViews?.includes(view)) || null
: state.defaultView,
homeDisplayOptions: {
...state.homeDisplayOptions,
...action.payload,
},
};
},
},
});

export const { setSettings, resetSettings, setViewFilters } =
settingsSlice.actions;
export const {
setSettings,
resetSettings,
setViewFilters,
setHomeDisplayOptions,
} = settingsSlice.actions;

export default settingsSlice.reducer;
5 changes: 5 additions & 0 deletions src/store/selectors/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ export const selectViewFilters = (view: HomeView) =>
return {} as ViewFilters;
}
});

export const selectHomeDisplayOptions = createSelector(
selectSettings,
(settings) => settings.homeDisplayOptions
);
7 changes: 6 additions & 1 deletion src/types/Settings.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import { Either } from './common';

export interface Settings {
defaultView: HomeView;
defaultView: HomeView | null;
apiKey: string;
darkMode: boolean;
autoPlayVideos: boolean;
recentVideosSeniority: VideosSeniority;
recentViewFilters: RecentViewFilters;
watchLaterViewFilters: WatchLaterViewFilters;
homeDisplayOptions: HomeDisplayOptions;
enableNotifications: boolean;
}

export interface HomeDisplayOptions {
hiddenViews: HomeView[];
}

export interface RecentViewFilters {
uncategorised: boolean;
viewed: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export default function ChannelFiltersDialog(props: ChannelFiltersDialogProps) {
{filters.map((filter, index) => (
<Filter
{...filter}
key={index}
onChange={(changes: Partial<ChannelFilter>) =>
handleChange(changes, index)
}
Expand Down
129 changes: 129 additions & 0 deletions src/ui/components/pages/Home/DisplayOptionsDialog/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import React, { useState } from 'react';
import {
Box,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
FormLabel,
FormControl,
FormGroup,
FormControlLabel,
Switch,
} from '@mui/material';
import { HomeView } from 'types';
import { useDidMountEffect } from 'hooks/useDidMountEffect';
import { useAppDispatch, useAppSelector } from 'store';
import { selectHomeDisplayOptions } from 'store/selectors/settings';
import DisplaySettingsIcon from '@mui/icons-material/DisplaySettings';
import { setHomeDisplayOptions } from 'store/reducers/settings';

interface DisplayOptionsDialogProps {
open: boolean;
onClose: () => void;
}

interface View {
label: string;
value: HomeView;
hidden: boolean;
}

export default function DisplayOptionsDialog(props: DisplayOptionsDialogProps) {
const { open, onClose } = props;
const displayOptions = useAppSelector(selectHomeDisplayOptions);
const dispatch = useAppDispatch();
const initialViews: View[] = [
{
label: 'All',
value: HomeView.All,
hidden: displayOptions.hiddenViews.includes(HomeView.All),
},
{
label: 'Recent',
value: HomeView.Recent,
hidden: displayOptions.hiddenViews.includes(HomeView.Recent),
},
{
label: 'Watch Later',
value: HomeView.WatchLater,
hidden: displayOptions.hiddenViews.includes(HomeView.WatchLater),
},
];
const [views, setViews] = useState(initialViews);

useDidMountEffect(() => {
if (open) {
setViews(initialViews);
}
}, [open]);

const handleViewToggle = (target: View) => {
setViews((state) =>
state.map((view) =>
view.value === target.value
? {
...view,
hidden: !view.hidden,
}
: view
)
);
};

const handleSave = () => {
dispatch(
setHomeDisplayOptions({
hiddenViews: views
.filter(({ hidden }) => hidden)
.map(({ value }) => value),
})
);
onClose();
};

const handleClose = () => {
onClose();
};

return (
<Dialog open={open} onClose={handleClose}>
<DialogContent>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
<DisplaySettingsIcon fontSize="large" />
<DialogTitle sx={{ padding: 0 }}>Display options</DialogTitle>
</Box>
<Box sx={{ pt: 2.5, minWidth: 420 }}>
<FormControl component="fieldset" variant="standard" focused={false}>
<FormLabel component="legend">Active views</FormLabel>
<FormGroup>
{views.map((view) => (
<FormControlLabel
onClick={() => handleViewToggle(view)}
key={view.value}
control={
<Switch
color="secondary"
checked={!view.hidden}
name={view.value}
/>
}
label={view.label}
/>
))}
</FormGroup>
</FormControl>
</Box>
</DialogContent>
<DialogActions sx={{ px: 2, pb: 2 }}>
<Button color="inherit" onClick={handleClose} autoFocus>
Cancel
</Button>
<Button color="secondary" variant="contained" onClick={handleSave}>
Save
</Button>
</DialogActions>
</Dialog>
);
}
2 changes: 1 addition & 1 deletion src/ui/components/pages/Home/TabActions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useAppSelector } from 'store';
import { selectActiveChannelsCount } from 'store/selectors/channels';

interface TabActionsProps {
tab: HomeView;
tab: HomeView | null;
recentVideosCount: number;
watchLaterVideosCount: number;
}
Expand Down
33 changes: 21 additions & 12 deletions src/ui/components/pages/Home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function Home(props: HomeProps) {
}
);
const watchLaterVideosCount = useAppSelector(selectWatchLaterVideosCount);
const { hiddenViews } = settings.homeDisplayOptions;

useEffect(() => {
if (activeTab !== settings.defaultView) {
Expand Down Expand Up @@ -57,25 +58,33 @@ export function Home(props: HomeProps) {
onChange={handleTabChange}
aria-label="tabs"
>
<Tab label="All" value={HomeView.All} />
<Tab
label="Recent"
value={HomeView.Recent}
badge={recentVideosCount.displayed}
/>
<Tab
label="Watch later"
value={HomeView.WatchLater}
badge={watchLaterVideosCount}
/>
{!hiddenViews.includes(HomeView.All) && (
<Tab label="All" value={HomeView.All} />
)}
{!hiddenViews.includes(HomeView.Recent) && (
<Tab
label="Recent"
value={HomeView.Recent}
badge={recentVideosCount.displayed}
/>
)}
{!hiddenViews.includes(HomeView.WatchLater) && (
<Tab
label="Watch later"
value={HomeView.WatchLater}
badge={watchLaterVideosCount}
/>
)}
</Tabs>
<TabActions
tab={activeTab}
recentVideosCount={recentVideosCount.total}
watchLaterVideosCount={watchLaterVideosCount}
/>
</Box>
<TabPanel tab={activeTab} onCountChange={handleCountChange} />
{activeTab && (
<TabPanel tab={activeTab} onCountChange={handleCountChange} />
)}
</Layout>
);
}
2 changes: 1 addition & 1 deletion src/ui/components/pages/Settings/Field/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Select from './Select';
import MenuItem from './MenuItem';
import Secret from './Secret';

type ValueType = string | number | boolean;
type ValueType = string | number | boolean | null;

type OptionType = {
label: string;
Expand Down
40 changes: 25 additions & 15 deletions src/ui/components/pages/Settings/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useMemo } from 'react';
import { Stack, Divider, Link } from '@mui/material';
import { Layout } from 'ui/components/shared';
import { HomeView, SettingType, VideosSeniority } from 'types';
Expand All @@ -20,13 +20,36 @@ import ClearVideosData from './ClearVideosData';

interface SettingsProps {}

const views = [
{
label: 'All',
value: HomeView.All,
},
{
label: 'Recent',
value: HomeView.Recent,
},
{
label: 'Watch later',
value: HomeView.WatchLater,
},
];

export function Settings(props: SettingsProps) {
const [lastCheckTime, setLastCheckTime] = useState(null);
const settings = useAppSelector(selectSettings);
const videos = useAppSelector(selectVideos);
const savedVideosSize = memorySizeOf(videos);
const dispatch = useAppDispatch();

const activeViews = useMemo(
() =>
views.filter(
({ value }) => !settings.homeDisplayOptions.hiddenViews.includes(value)
),
[settings.homeDisplayOptions.hiddenViews]
);

useEffect(() => {
if (isWebExtension) {
sendMessage('getLastCheckDate').then((date: string) => {
Expand All @@ -48,20 +71,7 @@ export function Settings(props: SettingsProps) {
onChange={(defaultView: HomeView) => {
dispatch(setSettings({ defaultView }));
}}
options={[
{
label: 'All',
value: HomeView.All,
},
{
label: 'Recent',
value: HomeView.Recent,
},
{
label: 'Watch later',
value: HomeView.WatchLater,
},
]}
options={activeViews}
type={SettingType.List}
/>
<ControlledField
Expand Down
2 changes: 1 addition & 1 deletion src/ui/components/shared/Sidebar/ListItemLink/Badge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Badge = styled(MuiBadge)(({ theme }) => ({
minWidth: 24,
height: 24,
fontSize: '0.75rem',
marginLeft: theme.spacing(3),
// marginLeft: theme.spacing(3),
borderRadius: theme.spacing(1.5),
},
}));
Expand Down
Loading

0 comments on commit 3939228

Please sign in to comment.